From bf52b68dcd1864fd35309f9aae19f146da5b774e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Aug 2010 06:30:04 +0000 Subject: [PATCH] minor changes to rna/python. - raise an exception when python calls is_property_set(name) or is_property_hidden(name) and the property does not exist. - added BLI_findstring_ptr(), which finds a named item in a listbase where that name is a pointer to a string. - replaced inline for loops with calls to BLI_findstring_ptr() and IDP_GetPropertyFromGroup(). --- source/blender/blenkernel/intern/idprop.c | 53 ++++++++---------- source/blender/blenlib/BLI_listbase.h | 1 + source/blender/blenlib/intern/listbase.c | 21 +++++++ source/blender/makesrna/intern/rna_access.c | 55 +++++++------------ source/blender/python/intern/bpy_rna.c | 35 ++++++++++-- source/blender/windowmanager/intern/wm.c | 9 +-- .../windowmanager/intern/wm_operators.c | 8 +-- 7 files changed, 101 insertions(+), 81 deletions(-) diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 2ccb33b088a..a0df73d6c42 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -27,6 +27,7 @@ #include #include +#include #include #include "BKE_idprop.h" @@ -491,47 +492,41 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src) void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) { IDProperty *loop; - for (loop=group->data.group.first; loop; loop=loop->next) { - if (BSTR_EQ(loop->name, prop->name)) { - BLI_insertlink(&group->data.group, loop, prop); - - BLI_remlink(&group->data.group, loop); - IDP_FreeProperty(loop); - MEM_freeN(loop); - return; - } + if((loop= IDP_GetPropertyFromGroup(group, prop->name))) { + BLI_insertlink(&group->data.group, loop, prop); + + BLI_remlink(&group->data.group, loop); + IDP_FreeProperty(loop); + MEM_freeN(loop); + } + else { + group->len++; + BLI_addtail(&group->data.group, prop); } - - group->len++; - BLI_addtail(&group->data.group, prop); } /*returns 0 if an id property with the same name exists and it failed, or 1 if it succeeded in adding to the group.*/ int IDP_AddToGroup(IDProperty *group, IDProperty *prop) { - IDProperty *loop; - for (loop=group->data.group.first; loop; loop=loop->next) { - if (BSTR_EQ(loop->name, prop->name)) return 0; + if(IDP_GetPropertyFromGroup(group, prop->name) == NULL) { + group->len++; + BLI_addtail(&group->data.group, prop); + return 1; } - group->len++; - BLI_addtail(&group->data.group, prop); - - return 1; + return 0; } int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew) { - IDProperty *loop; - for (loop=group->data.group.first; loop; loop=loop->next) { - if (BSTR_EQ(loop->name, pnew->name)) return 0; + if(IDP_GetPropertyFromGroup(group, pnew->name) == NULL) { + group->len++; + BLI_insertlink(&group->data.group, previous, pnew); + return 1; } - - group->len++; - BLI_insertlink(&group->data.group, previous, pnew); - return 1; + return 0; } void IDP_RemFromGroup(IDProperty *group, IDProperty *prop) @@ -542,11 +537,7 @@ void IDP_RemFromGroup(IDProperty *group, IDProperty *prop) IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name) { - IDProperty *loop; - for (loop=prop->data.group.first; loop; loop=loop->next) { - if (strcmp(loop->name, name)==0) return loop; - } - return NULL; + return (IDProperty *)BLI_findstring(&prop->data.group, name, offsetof(IDProperty, name)); } typedef struct IDPIter { diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 599487354c3..c4dc0894f80 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -45,6 +45,7 @@ void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); void *BLI_findlink(struct ListBase *listbase, int number); int BLI_findindex(struct ListBase *listbase, void *vlink); void *BLI_findstring(struct ListBase *listbase, const char *id, int offset); +void *BLI_findstring_ptr(struct ListBase *listbase, const char *id, int offset); int BLI_findstringindex(struct ListBase *listbase, const char *id, int offset); void BLI_freelistN(struct ListBase *listbase); void BLI_addtail(struct ListBase *listbase, void *vlink); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 0a6831558d1..776f2d085df 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -374,6 +374,27 @@ void *BLI_findstring(ListBase *listbase, const char *id, int offset) return NULL; } +void *BLI_findstring_ptr(ListBase *listbase, const char *id, int offset) +{ + Link *link= NULL; + const char *id_iter; + + if (listbase == NULL) return NULL; + + link= listbase->first; + while (link) { + /* exact copy of BLI_findstring(), except for this line */ + id_iter= *((const char **)(((const char *)link) + offset)); + + if(id[0] == id_iter[0] && strcmp(id, id_iter)==0) + return link; + + link= link->next; + } + + return NULL; +} + int BLI_findstringindex(ListBase *listbase, const char *id, int offset) { Link *link= NULL; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index b15f736ac76..8e7a2a8cab3 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -258,14 +259,10 @@ int RNA_struct_idproperties_check(StructRNA *srna) static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name) { IDProperty *group= RNA_struct_idproperties(ptr, 0); - IDProperty *idprop; - if(group) { - for(idprop=group->data.group.first; idprop; idprop=idprop->next) - if(strcmp(idprop->name, name) == 0) - return idprop; - } - + if(group) + return IDP_GetPropertyFromGroup(group, name); + return NULL; } @@ -577,9 +574,9 @@ FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier) FunctionRNA *func; StructRNA *type; for(type= ptr->type; type; type= type->base) { - for(func= type->functions.first; func; func= func->cont.next) { - if(strcmp(func->identifier, identifier)==0) - return func; + func= BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier)); + if(func) { + return func; } } return NULL; @@ -3592,7 +3589,8 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name) return 1; } else { - // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name); + /* python raises an error */ + /* printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name); */ return 0; } } @@ -3777,27 +3775,12 @@ int RNA_function_defined(FunctionRNA *func) PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index) { - PropertyRNA *parm; - int i; - - parm= func->cont.properties.first; - for(i= 0; parm; parm= parm->next, i++) - if(i==index) - return parm; - - return NULL; + return BLI_findlink(&func->cont.properties, index); } PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier) { - PropertyRNA *parm; - - parm= func->cont.properties.first; - for(; parm; parm= parm->next) - if(strcmp(parm->identifier, identifier)==0) - return parm; - - return NULL; + return BLI_findstring(&func->cont.properties, identifier, offsetof(PropertyRNA, identifier)); } const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func) @@ -3813,18 +3796,18 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, void *data; int alloc_size= 0, size; - parms->arg_count= 0; - parms->ret_count= 0; - + parms->arg_count= 0; + parms->ret_count= 0; + /* allocate data */ for(parm= func->cont.properties.first; parm; parm= parm->next) { alloc_size += rna_parameter_size_alloc(parm); - if(parm->flag & PROP_OUTPUT) - parms->ret_count++; - else - parms->arg_count++; - } + if(parm->flag & PROP_OUTPUT) + parms->ret_count++; + else + parms->arg_count++; + } parms->data= MEM_callocN(alloc_size, "RNA_parameter_list_create"); parms->func= func; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 5ad8af31a82..9b2248d1ed4 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2086,12 +2086,34 @@ static char pyrna_struct_is_property_set_doc[] = static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args) { + PropertyRNA *prop; char *name; + int ret; if (!PyArg_ParseTuple(args, "s:is_property_set", &name)) return NULL; - return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); + if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + PyErr_Format(PyExc_TypeError, "%.200s.is_property_set(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); + return NULL; + } + + /* double property lookup, could speed up */ + /* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */ + if(RNA_property_flag(prop) & PROP_IDPROPERTY) { + IDProperty *group= RNA_struct_idproperties(&self->ptr, 0); + if(group) { + ret= IDP_GetPropertyFromGroup(group, name) ? 1:0; + } + else { + ret= 0; + } + } + else { + ret= 1; + } + + return PyBool_FromLong(ret); } static char pyrna_struct_is_property_hidden_doc[] = @@ -2106,15 +2128,16 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject * { PropertyRNA *prop; char *name; - int hidden; if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name)) return NULL; - - prop= RNA_struct_find_property(&self->ptr, name); - hidden= (prop)? (RNA_property_flag(prop) & PROP_HIDDEN): 1; - return PyBool_FromLong(hidden); + if((prop= RNA_struct_find_property(&self->ptr, name)) == NULL) { + PyErr_Format(PyExc_TypeError, "%.200s.is_property_hidden(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name); + return NULL; + } + + return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN); } static char pyrna_struct_path_resolve_doc[] = diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index fcf8951d796..8d36711032b 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -26,7 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include "string.h" +#include +#include #include "DNA_windowmanager_types.h" @@ -149,9 +150,9 @@ MenuType *WM_menutype_find(const char *idname, int quiet) MenuType* mt; if (idname[0]) { - for(mt=menutypes.first; mt; mt=mt->next) - if(strcmp(idname, mt->idname)==0) - return mt; + mt= BLI_findstring(&menutypes, idname, offsetof(MenuType, idname)); + if(mt) + return mt; } if(!quiet) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index fef7f737c8a..23994905b96 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -103,11 +103,11 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet) char idname_bl[OP_MAX_TYPENAME]; // XXX, needed to support python style names without the _OT_ syntax WM_operator_bl_idname(idname_bl, idname); - + if (idname_bl[0]) { - for(ot= global_ops.first; ot; ot= ot->next) { - if(strncmp(ot->idname, idname_bl, OP_MAX_TYPENAME)==0) - return ot; + ot= BLI_findstring_ptr(&global_ops, idname_bl, offsetof(wmOperatorType, idname)); + if(ot) { + return ot; } }