diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index a7a739ea132..4532a1c091b 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -1950,46 +1951,46 @@ static void ui_selectcontext_apply(bContext *C, const int index = but->rnaindex; const bool use_delta = (selctx_data->is_copy == false); - union { - bool b; - int i; - float f; - char *str; - PointerRNA p; - } delta, min, max; + std::variant delta, min, max; const bool is_array = RNA_property_array_check(prop); const int rna_type = RNA_property_type(prop); if (rna_type == PROP_FLOAT) { - delta.f = use_delta ? (value - value_orig) : value; - RNA_property_float_range(&but->rnapoin, prop, &min.f, &max.f); + delta.emplace(use_delta ? (value - value_orig) : value); + float min_v, max_v; + RNA_property_float_range(&but->rnapoin, prop, &min_v, &max_v); + min.emplace(min_v); + max.emplace(max_v); } else if (rna_type == PROP_INT) { - delta.i = use_delta ? (int(value) - int(value_orig)) : int(value); - RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i); + delta.emplace(int(use_delta ? (value - value_orig) : value)); + int min_v, max_v; + RNA_property_int_range(&but->rnapoin, prop, &min_v, &max_v); + min.emplace(min_v); + max.emplace(max_v); } else if (rna_type == PROP_ENUM) { /* Not a delta in fact. */ - delta.i = RNA_property_enum_get(&but->rnapoin, prop); + delta.emplace(RNA_property_enum_get(&but->rnapoin, prop)); } else if (rna_type == PROP_BOOLEAN) { if (is_array) { /* Not a delta in fact. */ - delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index); + delta.emplace(RNA_property_boolean_get_index(&but->rnapoin, prop, index)); } else { /* Not a delta in fact. */ - delta.b = RNA_property_boolean_get(&but->rnapoin, prop); + delta.emplace(RNA_property_boolean_get(&but->rnapoin, prop)); } } else if (rna_type == PROP_POINTER) { /* Not a delta in fact. */ - delta.p = RNA_property_pointer_get(&but->rnapoin, prop); + delta.emplace(RNA_property_pointer_get(&but->rnapoin, prop)); } else if (rna_type == PROP_STRING) { /* Not a delta in fact. */ - delta.str = RNA_property_string_get_alloc(&but->rnapoin, prop, nullptr, 0, nullptr); + delta.emplace(RNA_property_string_get(&but->rnapoin, prop)); } # ifdef USE_ALLSELECT_LAYER_HACK @@ -2028,8 +2029,8 @@ static void ui_selectcontext_apply(bContext *C, PointerRNA lptr = other->ptr; if (rna_type == PROP_FLOAT) { - float other_value = use_delta ? (other->val_f + delta.f) : delta.f; - CLAMP(other_value, min.f, max.f); + float other_value = std::get(delta) + (use_delta ? other->val_f : 0.0f); + CLAMP(other_value, std::get(min), std::get(max)); if (is_array) { RNA_property_float_set_index(&lptr, lprop, index, other_value); } @@ -2038,8 +2039,8 @@ static void ui_selectcontext_apply(bContext *C, } } else if (rna_type == PROP_INT) { - int other_value = use_delta ? (other->val_i + delta.i) : delta.i; - CLAMP(other_value, min.i, max.i); + int other_value = std::get(delta) + (use_delta ? other->val_i : 0); + CLAMP(other_value, std::get(min), std::get(max)); if (is_array) { RNA_property_int_set_index(&lptr, lprop, index, other_value); } @@ -2048,33 +2049,30 @@ static void ui_selectcontext_apply(bContext *C, } } else if (rna_type == PROP_BOOLEAN) { - const bool other_value = delta.b; + const bool other_value = std::get(delta); if (is_array) { RNA_property_boolean_set_index(&lptr, lprop, index, other_value); } else { - RNA_property_boolean_set(&lptr, lprop, delta.b); + RNA_property_boolean_set(&lptr, lprop, other_value); } } else if (rna_type == PROP_ENUM) { - const int other_value = delta.i; + const int other_value = std::get(delta); BLI_assert(!is_array); RNA_property_enum_set(&lptr, lprop, other_value); } else if (rna_type == PROP_POINTER) { - const PointerRNA other_value = delta.p; + const PointerRNA &other_value = std::get(delta); RNA_property_pointer_set(&lptr, lprop, other_value, nullptr); } else if (rna_type == PROP_STRING) { - const char *other_value = delta.str; - RNA_property_string_set(&lptr, lprop, other_value); + const std::string &other_value = std::get(delta); + RNA_property_string_set(&lptr, lprop, other_value.c_str()); } RNA_property_update(C, &lptr, prop); } - if (rna_type == PROP_STRING) { - MEM_freeN(delta.str); - } } } diff --git a/source/blender/makesrna/RNA_access.hh b/source/blender/makesrna/RNA_access.hh index b28f79e3d2c..adf13e0f936 100644 --- a/source/blender/makesrna/RNA_access.hh +++ b/source/blender/makesrna/RNA_access.hh @@ -405,6 +405,7 @@ bool RNA_property_float_set_default(PropertyRNA *prop, float value); void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values); float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index); +std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop); void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value); char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 5cb8e7b1f5d..6bfc74895de 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -3509,6 +3509,36 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i return value; } +std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop) +{ + StringPropertyRNA *sprop = reinterpret_cast(prop); + IDProperty *idprop; + + BLI_assert(RNA_property_type(prop) == PROP_STRING); + + if ((idprop = rna_idproperty_check(&prop, ptr))) { + /* NOTE: `std::string` does support NULL char in its data. */ + return std::string{IDP_String(idprop), size_t(idprop->len)}; + } + + if (!sprop->get && !sprop->get_ex) { + return std::string{sprop->defaultvalue}; + } + + size_t length = size_t(RNA_property_string_length(ptr, prop)); + std::string string_ret{}; + string_ret.reserve(length + 1); + + if (sprop->get) { + sprop->get(ptr, string_ret.data()); + } + else { /* if (sprop->get_ex) */ + sprop->get_ex(ptr, prop, string_ret.data()); + } + + return string_ret; +} + void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value) { StringPropertyRNA *sprop = (StringPropertyRNA *)prop;