Refactor: UI: Use std::variant instead of Union for non-trivial data.

Unions make handling of non-trivial data 'members'... non-trivial.

Since `PointerRNA` is going to become non-trivial, this commit replaces
the Union storing delta, min and max values of editied RNA properties
in `ui_selectcontext_apply`, into a `std::variant`.

It also adds a new accessor to RNA string properties, returning a
`std::string` data, and uses this type to store string properties values
in `ui_selectcontext_apply`.

Pull Request: https://projects.blender.org/blender/blender/pulls/124727
This commit is contained in:
Bastien Montagne
2024-07-15 16:05:34 +02:00
committed by Gitea
parent d7a7491518
commit 50076993f3
3 changed files with 58 additions and 29 deletions

View File

@@ -12,6 +12,7 @@
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <variant>
#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<bool, int, float, std::string, PointerRNA> 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<float>(use_delta ? (value - value_orig) : value);
float min_v, max_v;
RNA_property_float_range(&but->rnapoin, prop, &min_v, &max_v);
min.emplace<float>(min_v);
max.emplace<float>(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>(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<int>(min_v);
max.emplace<int>(max_v);
}
else if (rna_type == PROP_ENUM) {
/* Not a delta in fact. */
delta.i = RNA_property_enum_get(&but->rnapoin, prop);
delta.emplace<int>(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<bool>(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<bool>(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<PointerRNA>(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<std::string>(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<float>(delta) + (use_delta ? other->val_f : 0.0f);
CLAMP(other_value, std::get<float>(min), std::get<float>(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<int>(delta) + (use_delta ? other->val_i : 0);
CLAMP(other_value, std::get<int>(min), std::get<int>(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<bool>(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<int>(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<PointerRNA>(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<std::string>(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);
}
}
}

View File

@@ -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,

View File

@@ -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<StringPropertyRNA *>(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;