diff options
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 3 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access_compare_override.c | 67 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 82 |
6 files changed, 119 insertions, 36 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index d6f037f64a4..c37ba35991e 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -649,6 +649,7 @@ bool BKE_lib_override_library_status_check_local(Main *bmain, ID *local) &rnaptr_local, &rnaptr_reference, NULL, + 0, local->override_library, RNA_OVERRIDE_COMPARE_IGNORE_NON_OVERRIDABLE | RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN, @@ -712,6 +713,7 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local) &rnaptr_local, &rnaptr_reference, NULL, + 0, local->override_library, RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN, NULL)) { @@ -771,6 +773,7 @@ bool BKE_lib_override_library_operations_create(Main *bmain, &rnaptr_local, &rnaptr_reference, NULL, + 0, local->override_library, RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE, &report_flags); diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 65c43ebc151..7247f468245 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1465,6 +1465,7 @@ bool RNA_struct_override_matches(struct Main *bmain, struct PointerRNA *ptr_local, struct PointerRNA *ptr_reference, const char *root_path, + const size_t root_path_len, struct IDOverrideLibrary *override, const eRNAOverrideMatch flags, eRNAOverrideMatchResult *r_report_flags); diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 265e83ddcba..28ee5eca723 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -18,6 +18,8 @@ * \ingroup RNA */ +#include <string.h> + #include "MEM_guardedalloc.h" #include "DNA_ID.h" @@ -28,7 +30,7 @@ #include "BLI_string.h" #include "BLI_utildefines.h" -// #define DEBUG_OVERRIDE_TIMEIT +//#define DEBUG_OVERRIDE_TIMEIT #ifdef DEBUG_OVERRIDE_TIMEIT # include "PIL_time_utildefines.h" @@ -180,6 +182,7 @@ static int rna_property_override_diff(Main *bmain, PropertyRNA *prop_a, PropertyRNA *prop_b, const char *rna_path, + const size_t rna_path_len, eRNACompareMode mode, IDOverrideLibrary *override, const int flags, @@ -191,7 +194,7 @@ bool RNA_property_equals( BLI_assert(ELEM(mode, RNA_EQ_STRICT, RNA_EQ_UNSET_MATCH_ANY, RNA_EQ_UNSET_MATCH_NONE)); return (rna_property_override_diff( - bmain, ptr_a, ptr_b, prop, NULL, NULL, NULL, mode, NULL, 0, NULL) == 0); + bmain, ptr_a, ptr_b, prop, NULL, NULL, NULL, 0, mode, NULL, 0, NULL) == 0); } bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACompareMode mode) @@ -249,6 +252,7 @@ static int rna_property_override_diff(Main *bmain, PropertyRNA *prop_a, PropertyRNA *prop_b, const char *rna_path, + const size_t rna_path_len, eRNACompareMode mode, IDOverrideLibrary *override, const int flags, @@ -363,6 +367,7 @@ static int rna_property_override_diff(Main *bmain, mode, override, rna_path, + rna_path_len, diff_flags, &override_changed); if (override_changed && r_report_flags) { @@ -568,6 +573,7 @@ bool RNA_struct_override_matches(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, const char *root_path, + const size_t root_path_len, IDOverrideLibrary *override, const eRNAOverrideMatch flags, eRNAOverrideMatchResult *r_report_flags) @@ -649,31 +655,51 @@ bool RNA_struct_override_matches(Main *bmain, #endif #define RNA_PATH_BUFFSIZE 8192 -#define RNA_PATH_PRINTF(_str, ...) \ - if (BLI_snprintf(rna_path, RNA_PATH_BUFFSIZE, (_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE) { \ - rna_path = BLI_sprintfN((_str), __VA_ARGS__); \ - } \ - (void)0 -#define RNA_PATH_FREE \ - if (rna_path != rna_path_buffer) \ - MEM_freeN(rna_path) char rna_path_buffer[RNA_PATH_BUFFSIZE]; char *rna_path = rna_path_buffer; + size_t rna_path_len = 0; /* XXX TODO this will have to be refined to handle collections insertions, and array items */ if (root_path) { + BLI_assert(strlen(root_path) == root_path_len); + + const char *prop_name = RNA_property_identifier(prop_local); + const size_t prop_name_len = strlen(prop_name); + /* Inlined building, much much more efficient. */ if (prop_local->magic == RNA_MAGIC) { - RNA_PATH_PRINTF("%s.%s", root_path, RNA_property_identifier(prop_local)); + rna_path_len = root_path_len + 1 + prop_name_len; + if (rna_path_len >= RNA_PATH_BUFFSIZE) { + rna_path = MEM_mallocN(rna_path_len + 1, __func__); + } + + memcpy(rna_path, root_path, root_path_len); + rna_path[root_path_len] = '.'; + memcpy(rna_path + root_path_len + 1, prop_name, prop_name_len); + rna_path[rna_path_len] = '\0'; } else { - RNA_PATH_PRINTF("%s[\"%s\"]", root_path, RNA_property_identifier(prop_local)); + rna_path_len = root_path_len + 2 + prop_name_len + 2; + if (rna_path_len >= RNA_PATH_BUFFSIZE) { + rna_path = MEM_mallocN(rna_path_len + 1, __func__); + } + + memcpy(rna_path, root_path, root_path_len); + rna_path[root_path_len] = '['; + rna_path[root_path_len + 1] = '"'; + memcpy(rna_path + root_path_len + 2, prop_name, prop_name_len); + rna_path[root_path_len + 2 + prop_name_len] = '"'; + rna_path[root_path_len + 2 + prop_name_len + 1] = ']'; + rna_path[rna_path_len] = '\0'; } } else { /* This is rather slow, but is not much called, so not really worth optimizing. */ rna_path = RNA_path_from_ID_to_property(ptr_local, prop_local); + if (rna_path != NULL) { + rna_path_len = strlen(rna_path); + } } if (rna_path == NULL) { continue; @@ -684,7 +710,10 @@ bool RNA_struct_override_matches(Main *bmain, IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(override, rna_path); if (ignore_overridden && op != NULL) { BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); - RNA_PATH_FREE; + + if (rna_path != rna_path_buffer) { + MEM_freeN(rna_path); + } continue; } @@ -702,6 +731,7 @@ bool RNA_struct_override_matches(Main *bmain, prop_local, prop_reference, rna_path, + rna_path_len, RNA_EQ_STRICT, override, flags, @@ -769,17 +799,18 @@ bool RNA_struct_override_matches(Main *bmain, matching = false; if (!(do_create || do_restore)) { /* Since we have no 'changing' action allowed, we can break here. */ - MEM_SAFE_FREE(rna_path); + if (rna_path != rna_path_buffer) { + MEM_freeN(rna_path); + } break; } } } - RNA_PATH_FREE; - + if (rna_path != rna_path_buffer) { + MEM_freeN(rna_path); + } #undef RNA_PATH_BUFFSIZE -#undef RNA_PATH_PRINTF -#undef RNA_PATH_FREE } RNA_property_collection_end(&iter); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 44f118a8744..0783addd78b 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -498,6 +498,7 @@ int rna_property_override_diff_default(struct Main *bmain, const int mode, struct IDOverrideLibrary *override, const char *rna_path, + const size_t rna_path_len, const int flags, bool *r_override_changed); diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index 0e3fc851a9b..bc83ed25ce5 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -176,6 +176,7 @@ typedef int (*RNAPropOverrideDiff)(struct Main *bmain, const int mode, struct IDOverrideLibrary *override, const char *rna_path, + const size_t rna_path_len, const int flags, bool *r_override_changed); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index d7e93975d31..bf1dcfbbf25 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1248,6 +1248,7 @@ static int rna_property_override_diff_propptr(Main *bmain, const bool no_prop_name, IDOverrideLibrary *override, const char *rna_path, + size_t rna_path_len, const char *rna_itemname_a, const char *rna_itemname_b, const int rna_itemindex_a, @@ -1324,16 +1325,7 @@ static int rna_property_override_diff_propptr(Main *bmain, char extended_rna_path_buffer[RNA_PATH_BUFFSIZE]; char *extended_rna_path = extended_rna_path_buffer; - -# define RNA_PATH_PRINTF(_str, ...) \ - if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, (_str), __VA_ARGS__) >= \ - RNA_PATH_BUFFSIZE - 1) { \ - extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); \ - } \ - (void)0 -# define RNA_PATH_FREE() \ - if (extended_rna_path != extended_rna_path_buffer && extended_rna_path != rna_path) \ - MEM_freeN(extended_rna_path) + size_t extended_rna_path_len = 0; /* There may be a propname defined in some cases, while no actual name set * (e.g. happens with point cache), in that case too we want to fall back to index. @@ -1342,31 +1334,82 @@ static int rna_property_override_diff_propptr(Main *bmain, if ((rna_itemname_a != NULL && rna_itemname_a[0] != '\0') && (rna_itemname_b != NULL && rna_itemname_b[0] != '\0')) { BLI_assert(STREQ(rna_itemname_a, rna_itemname_b)); + char esc_item_name[RNA_PATH_BUFFSIZE]; - BLI_strescape(esc_item_name, rna_itemname_a, RNA_PATH_BUFFSIZE); - RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name); + const size_t esc_item_name_len = BLI_strescape( + esc_item_name, rna_itemname_a, RNA_PATH_BUFFSIZE); + extended_rna_path_len = rna_path_len + 2 + esc_item_name_len + 2; + if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) { + extended_rna_path = MEM_mallocN(extended_rna_path_len + 1, __func__); + } + + memcpy(extended_rna_path, rna_path, rna_path_len); + extended_rna_path[rna_path_len] = '['; + extended_rna_path[rna_path_len + 1] = '"'; + memcpy(extended_rna_path + rna_path_len + 2, esc_item_name, esc_item_name_len); + extended_rna_path[rna_path_len + 2 + esc_item_name_len] = '"'; + extended_rna_path[rna_path_len + 2 + esc_item_name_len + 1] = ']'; + extended_rna_path[extended_rna_path_len] = '\0'; } else if (rna_itemindex_a != -1) { /* Based on index... */ BLI_assert(rna_itemindex_a == rna_itemindex_b); - RNA_PATH_PRINTF("%s[%d]", rna_path, rna_itemindex_a); + + /* low-level specific highly-efficient conversion of positive integer to string. */ + char item_index_buff[32]; + size_t item_index_buff_len = 0; + if (rna_itemindex_a == 0) { + item_index_buff[0] = '0'; + item_index_buff_len = 1; + } + else { + uint index; + for (index = rna_itemindex_a; + index > 0 && item_index_buff_len < sizeof(item_index_buff); + index /= 10) { + item_index_buff[item_index_buff_len++] = '0' + (char)(index % 10); + } + BLI_assert(index == 0); + } + + extended_rna_path_len = rna_path_len + item_index_buff_len + 2; + if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) { + extended_rna_path = MEM_mallocN(extended_rna_path_len + 1, __func__); + } + + memcpy(extended_rna_path, rna_path, rna_path_len); + extended_rna_path[rna_path_len] = '['; + for (size_t i = 1; i <= item_index_buff_len; i++) { + /* The first loop above generated inverted string representation of our index number. + */ + extended_rna_path[rna_path_len + i] = item_index_buff[item_index_buff_len - i]; + } + extended_rna_path[rna_path_len + 1 + item_index_buff_len] = ']'; + extended_rna_path[extended_rna_path_len] = '\0'; } else { extended_rna_path = (char *)rna_path; + extended_rna_path_len = rna_path_len; } } eRNAOverrideMatchResult report_flags = 0; - const bool match = RNA_struct_override_matches( - bmain, propptr_a, propptr_b, extended_rna_path, override, flags, &report_flags); + const bool match = RNA_struct_override_matches(bmain, + propptr_a, + propptr_b, + extended_rna_path, + extended_rna_path_len, + override, + flags, + &report_flags); if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) { *r_override_changed = true; } - RNA_PATH_FREE(); + if (extended_rna_path != extended_rna_path_buffer && extended_rna_path != rna_path) { + MEM_freeN(extended_rna_path); + } # undef RNA_PATH_BUFFSIZE -# undef RNA_PATH_PRINTF -# undef RNA_PATH_FREE return !match; } @@ -1395,6 +1438,7 @@ int rna_property_override_diff_default(Main *bmain, const int mode, IDOverrideLibrary *override, const char *rna_path, + const size_t rna_path_len, const int flags, bool *r_override_changed) { @@ -1684,6 +1728,7 @@ int rna_property_override_diff_default(Main *bmain, no_prop_name, override, rna_path, + rna_path_len, NULL, NULL, -1, @@ -1844,6 +1889,7 @@ int rna_property_override_diff_default(Main *bmain, no_prop_name, override, rna_path, + rna_path_len, propname_a, propname_b, idx_a, |