From ea0d1c74e4930657cceeaee22ca6a41258653068 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 20 Nov 2012 19:44:20 +0000 Subject: Fix #33227: custom keymap syncing didn't work well always when adding/removing properties from operator, now it compares at RNA rather than ID property level, which is more accurate. --- source/blender/makesrna/RNA_access.h | 5 + source/blender/makesrna/intern/rna_access.c | 141 +++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 1 deletion(-) (limited to 'source/blender/makesrna') diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index c9b44be06f9..3afafdded64 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1054,6 +1054,11 @@ __attribute__ ((format(printf, 1, 2))) #endif ; +/* Equals test (skips pointers and collections) */ + +int RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop); +int RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b); + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index deb4094cb45..07febfb85f4 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -5721,7 +5721,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i /* get the length of the array to work with */ len = RNA_property_array_length(ptr, prop); - fromlen = RNA_property_array_length(ptr, prop); + fromlen = RNA_property_array_length(fromptr, prop); if (len != fromlen) return 0; @@ -5835,3 +5835,142 @@ void _RNA_warning(const char *format, ...) } #endif } + +int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) +{ + /* get the length of the array to work with */ + int len = RNA_property_array_length(a, prop); + int fromlen = RNA_property_array_length(b, prop); + + if (len != fromlen) + return 0; + + /* get and set the default values as appropriate for the various types */ + switch (RNA_property_type(prop)) { + case PROP_BOOLEAN: { + if (len) { + int fixed_a[16], fixed_b[16]; + int *array_a, *array_b; + int equals; + + array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; + array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; + + RNA_property_boolean_get_array(a, prop, array_a); + RNA_property_boolean_get_array(b, prop, array_b); + + equals = memcmp(array_a, array_b, sizeof(int) * len) == 0; + + if (array_a != fixed_a) MEM_freeN(array_a); + if (array_b != fixed_b) MEM_freeN(array_b); + + return equals; + } + else { + int value = RNA_property_boolean_get(a, prop); + return value == RNA_property_boolean_get(b, prop); + } + } + + case PROP_INT: { + if (len) { + int fixed_a[16], fixed_b[16]; + int *array_a, *array_b; + int equals; + + array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; + array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; + + RNA_property_int_get_array(a, prop, array_a); + RNA_property_int_get_array(b, prop, array_b); + + equals = memcmp(array_a, array_b, sizeof(int) * len) == 0; + + if (array_a != fixed_a) MEM_freeN(array_a); + if (array_b != fixed_b) MEM_freeN(array_b); + + return equals; + } + else { + int value = RNA_property_int_get(a, prop); + return value == RNA_property_int_get(b, prop); + } + } + + case PROP_FLOAT: { + if (len) { + float fixed_a[16], fixed_b[16]; + float *array_a, *array_b; + int equals; + + array_a = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_a; + array_b = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_b; + + RNA_property_float_get_array(a, prop, array_a); + RNA_property_float_get_array(b, prop, array_b); + + equals = memcmp(array_a, array_b, sizeof(float) * len) == 0; + + if (array_a != fixed_a) MEM_freeN(array_a); + if (array_b != fixed_b) MEM_freeN(array_b); + + return equals; + } + else { + float value = RNA_property_float_get(a, prop); + return value == RNA_property_float_get(b, prop); + } + } + + case PROP_ENUM: { + int value = RNA_property_enum_get(a, prop); + return value == RNA_property_enum_get(b, prop); + } + + case PROP_STRING: { + char fixed_a[128], fixed_b[128]; + int len_a, len_b; + char *value_a = RNA_property_string_get_alloc(a, prop, fixed_a, sizeof(fixed_a), &len_a); + char *value_b = RNA_property_string_get_alloc(b, prop, fixed_b, sizeof(fixed_b), &len_b); + int equals = strcmp(value_a, value_b) == 0; + + if (value_a != fixed_a) MEM_freeN(value_a); + if (value_b != fixed_b) MEM_freeN(value_b); + + return equals; + } + + default: + break; + } + + return 1; +} + +int RNA_struct_equals(PointerRNA *a, PointerRNA *b) +{ + CollectionPropertyIterator iter; + CollectionPropertyRNA *citerprop; + PropertyRNA *iterprop; + int equals = 1; + + if (a->type != b->type) + return 0; + + iterprop = RNA_struct_iterator_property(a->type); + citerprop = (CollectionPropertyRNA *)rna_ensure_property(iterprop); + + RNA_property_collection_begin(a, iterprop, &iter); + for (; iter.valid; RNA_property_collection_next(&iter)) { + PropertyRNA *prop = iter.ptr.data; + + if (!RNA_property_equals(a, b, prop)) { + equals = 0; + break; + } + } + RNA_property_collection_end(&iter); + + return equals; +} + -- cgit v1.2.3