From 07ed869b94fa8acf18d64864c6d8662bfbec33dd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Feb 2022 20:07:54 +1100 Subject: [PATCH] RNA: add RNA_collection_is_empty & RNA_property_collection_is_empty Some collections needed to be iterated over to count their length. Provide a function to check if the collection is empty to avoid this. --- .../blender/editors/curve/editcurve_paint.c | 2 +- source/blender/editors/space_clip/clip_ops.c | 2 +- .../editors/space_sequencer/sequencer_add.c | 8 ++++--- source/blender/makesrna/RNA_access.h | 6 ++++++ source/blender/makesrna/intern/rna_access.c | 21 +++++++++++++++++++ .../shader/nodes/node_shader_vertex_color.cc | 2 +- source/blender/python/intern/bpy_rna.c | 9 +------- 7 files changed, 36 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index eee806898f6..0d6db8743af 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -577,7 +577,7 @@ static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke) /* Using an empty stroke complicates logic later, * it's simplest to disallow early on (see: T94085). */ - if (RNA_collection_length(op->ptr, "stroke") == 0) { + if (RNA_collection_is_empty(op->ptr, "stroke")) { MEM_freeN(cdd); BKE_report(op->reports, RPT_ERROR, "The \"stroke\" cannot be empty"); return false; diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 64ac20123d9..311f3719864 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -186,7 +186,7 @@ static int open_exec(bContext *C, wmOperator *op) MovieClip *clip = NULL; char str[FILE_MAX]; - if (RNA_collection_length(op->ptr, "files")) { + if (!RNA_collection_is_empty(op->ptr, "files")) { PointerRNA fileptr; PropertyRNA *prop; char dir_only[FILE_MAX], file_only[FILE_MAX]; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index f371c663416..e5f267bb9fa 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -747,7 +747,8 @@ static int sequencer_add_movie_strip_invoke(bContext *C, RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); /* This is for drag and drop. */ - if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) || + if ((RNA_struct_property_is_set(op->ptr, "files") && + !RNA_collection_is_empty(op->ptr, "files")) || RNA_struct_property_is_set(op->ptr, "filepath")) { sequencer_generic_invoke_xy__internal(C, op, SEQPROP_NOPATHS, SEQ_TYPE_MOVIE); return sequencer_add_movie_strip_exec(C, op); @@ -901,7 +902,8 @@ static int sequencer_add_sound_strip_invoke(bContext *C, const wmEvent *UNUSED(event)) { /* This is for drag and drop. */ - if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) || + if ((RNA_struct_property_is_set(op->ptr, "files") && + !RNA_collection_is_empty(op->ptr, "files")) || RNA_struct_property_is_set(op->ptr, "filepath")) { sequencer_generic_invoke_xy__internal(C, op, SEQPROP_NOPATHS, SEQ_TYPE_SOUND_RAM); return sequencer_add_sound_strip_exec(C, op); @@ -1094,7 +1096,7 @@ static int sequencer_add_image_strip_invoke(bContext *C, RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); /* Name set already by drag and drop. */ - if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) { + if (RNA_struct_property_is_set(op->ptr, "files") && !RNA_collection_is_empty(op->ptr, "files")) { sequencer_generic_invoke_xy__internal( C, op, SEQPROP_ENDFRAME | SEQPROP_NOPATHS, SEQ_TYPE_IMAGE); return sequencer_add_image_strip_exec(C, op); diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 5441cf44ac9..eb25733a88a 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1117,6 +1117,11 @@ void RNA_property_collection_next(CollectionPropertyIterator *iter); void RNA_property_collection_skip(CollectionPropertyIterator *iter, int num); void RNA_property_collection_end(CollectionPropertyIterator *iter); int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop); +/** + * Return true when `RNA_property_collection_length(ptr, prop) == 0`, + * without having to iterate over items in the collection (needed for some kinds of collections). + */ +bool RNA_property_collection_is_empty(PointerRNA *ptr, PropertyRNA *prop); int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr); int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, @@ -1445,6 +1450,7 @@ void RNA_pointer_add(PointerRNA *ptr, const char *name); void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter); int RNA_collection_length(PointerRNA *ptr, const char *name); +bool RNA_collection_is_empty(PointerRNA *ptr, const char *name); void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value); void RNA_collection_clear(PointerRNA *ptr, const char *name); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 8189dc6b16f..6c3b46c4408 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3753,6 +3753,16 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop) return length; } +bool RNA_property_collection_is_empty(PointerRNA *ptr, PropertyRNA *prop) +{ + BLI_assert(RNA_property_type(prop) == PROP_COLLECTION); + CollectionPropertyIterator iter; + RNA_property_collection_begin(ptr, prop, &iter); + bool test = iter.valid; + RNA_property_collection_end(&iter); + return !test; +} + /* This helper checks whether given collection property itself is editable (we only currently * support a limited set of operations, insertion of new items, and re-ordering of those new items * exclusively). */ @@ -6417,6 +6427,17 @@ int RNA_collection_length(PointerRNA *ptr, const char *name) return 0; } +bool RNA_collection_is_empty(PointerRNA *ptr, const char *name) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, name); + + if (prop) { + return RNA_property_collection_is_empty(ptr, prop); + } + printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name); + return false; +} + bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost) { prop = rna_ensure_property(prop); diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc index 39c32edfe90..95e6e42cdff 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc @@ -23,7 +23,7 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); if (U.experimental.use_sculpt_vertex_colors && - RNA_collection_length(&dataptr, "sculpt_vertex_colors")) { + !RNA_collection_is_empty(&dataptr, "sculpt_vertex_colors")) { uiItemPointerR( layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL); } diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 2e0dfc515d1..316cfe4d8b1 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2192,16 +2192,9 @@ static int pyrna_prop_array_bool(BPy_PropertyRNA *self) static int pyrna_prop_collection_bool(BPy_PropertyRNA *self) { - /* No callback defined, just iterate and find the nth item. */ - CollectionPropertyIterator iter; - int test; - PYRNA_PROP_CHECK_INT(self); - RNA_property_collection_begin(&self->ptr, self->prop, &iter); - test = iter.valid; - RNA_property_collection_end(&iter); - return test; + return !RNA_property_collection_is_empty(&self->ptr, self->prop); } /* notice getting the length of the collection is avoided unless negative