[Bf-blender-cvs] [07b2aaa8c78] refactor-idprop-ui-data: Don't apply any changes on failure, refactor with `IDP_ui_data_free_unique_contents`
Hans Goudey
noreply at git.blender.org
Fri Aug 6 19:14:04 CEST 2021
Commit: 07b2aaa8c78c85690e8296f8e5ef316cb636fe84
Author: Hans Goudey
Date: Fri Aug 6 12:12:04 2021 -0500
Branches: refactor-idprop-ui-data
https://developer.blender.org/rB07b2aaa8c78c85690e8296f8e5ef316cb636fe84
Don't apply any changes on failure, refactor with `IDP_ui_data_free_unique_contents`
===================================================================
M source/blender/blenkernel/BKE_idprop.h
M source/blender/blenkernel/intern/idprop.c
M source/blender/makesdna/DNA_ID.h
M source/blender/modifiers/intern/MOD_nodes.cc
M source/blender/python/generic/idprop_py_ui_api.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index a6372cc490c..c28ac63388b 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -230,7 +230,9 @@ typedef enum eIDPropertyUIDataType {
bool IDP_ui_data_supported(const struct IDProperty *prop);
eIDPropertyUIDataType IDP_ui_data_type(const struct IDProperty *prop);
void IDP_ui_data_free(struct IDProperty *prop);
-void IDP_ui_data_free_contents(struct IDPropertyUIData *ui_data, const eIDPropertyUIDataType type);
+void IDP_ui_data_free_unique_contents(struct IDPropertyUIData *ui_data,
+ eIDPropertyUIDataType type,
+ const struct IDPropertyUIData *other);
struct IDPropertyUIData *IDP_ui_data_ensure(struct IDProperty *prop);
struct IDPropertyUIData *IDP_ui_data_copy(const struct IDProperty *prop);
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 0cbf2f3b515..786df14756a 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -1096,38 +1096,80 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
return prop;
}
-void IDP_ui_data_free_contents(IDPropertyUIData *ui_data, const eIDPropertyUIDataType type)
+/**
+ * Free allocated pointers in the UI data that isn't shared with the UI data in the #other
+ * argument. Useful for returning early on failure when updating UI data in place, or when
+ * replacing a subset of the UI data's allocated pointers.
+ */
+void IDP_ui_data_free_unique_contents(IDPropertyUIData *ui_data,
+ const eIDPropertyUIDataType type,
+ const IDPropertyUIData *other)
{
+ if (ui_data->description != other->description) {
+ MEM_SAFE_FREE(ui_data->description);
+ }
+
switch (type) {
case IDP_UI_DATA_TYPE_STRING: {
+ const IDPropertyUIDataString *other_string = (const IDPropertyUIDataString *)other;
IDPropertyUIDataString *ui_data_string = (IDPropertyUIDataString *)ui_data;
- MEM_SAFE_FREE(ui_data_string->default_value);
+ if (ui_data_string->default_value != other_string->default_value) {
+ MEM_SAFE_FREE(ui_data_string->default_value);
+ }
break;
}
case IDP_UI_DATA_TYPE_ID: {
break;
}
case IDP_UI_DATA_TYPE_INT: {
+ const IDPropertyUIDataInt *other_int = (const IDPropertyUIDataInt *)other;
IDPropertyUIDataInt *ui_data_int = (IDPropertyUIDataInt *)ui_data;
- MEM_SAFE_FREE(ui_data_int->default_array);
+ if (ui_data_int->default_array != other_int->default_array) {
+ MEM_SAFE_FREE(ui_data_int->default_array);
+ }
break;
}
case IDP_UI_DATA_TYPE_FLOAT: {
+ const IDPropertyUIDataFloat *other_float = (const IDPropertyUIDataFloat *)other;
IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)ui_data;
- MEM_SAFE_FREE(ui_data_float->default_array);
+ if (ui_data_float->default_array != other_float->default_array) {
+ MEM_SAFE_FREE(ui_data_float->default_array);
+ }
break;
}
case IDP_UI_DATA_TYPE_UNSUPPORTED: {
break;
}
}
-
- MEM_SAFE_FREE(ui_data->description);
}
void IDP_ui_data_free(IDProperty *prop)
{
- IDP_ui_data_free_contents(prop->ui_data, IDP_ui_data_type(prop));
+ switch (IDP_ui_data_type(prop)) {
+ case IDP_UI_DATA_TYPE_STRING: {
+ IDPropertyUIDataString *ui_data_string = (IDPropertyUIDataString *)prop->ui_data;
+ MEM_SAFE_FREE(ui_data_string->default_value);
+ break;
+ }
+ case IDP_UI_DATA_TYPE_ID: {
+ break;
+ }
+ case IDP_UI_DATA_TYPE_INT: {
+ IDPropertyUIDataInt *ui_data_int = (IDPropertyUIDataInt *)prop->ui_data;
+ MEM_SAFE_FREE(ui_data_int->default_array);
+ break;
+ }
+ case IDP_UI_DATA_TYPE_FLOAT: {
+ IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data;
+ MEM_SAFE_FREE(ui_data_float->default_array);
+ break;
+ }
+ case IDP_UI_DATA_TYPE_UNSUPPORTED: {
+ break;
+ }
+ }
+
+ MEM_SAFE_FREE(prop->ui_data->description);
MEM_freeN(prop->ui_data);
prop->ui_data = NULL;
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 8f73ac0ee48..beaad31e228 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -70,7 +70,7 @@ typedef struct IDPropertyUIData {
/* IDP_UI_DATA_TYPE_INT */
typedef struct IDPropertyUIDataInt {
- IDPropertyUIData generic_ui_data;
+ IDPropertyUIData base;
int *default_array; /* Only for array properties. */
int default_array_len;
char _pad[4];
@@ -85,7 +85,7 @@ typedef struct IDPropertyUIDataInt {
/* IDP_UI_DATA_TYPE_FLOAT */
typedef struct IDPropertyUIDataFloat {
- IDPropertyUIData generic_ui_data;
+ IDPropertyUIData base;
double *default_array; /* Only for array properties. */
int default_array_len;
char _pad[4];
@@ -102,13 +102,13 @@ typedef struct IDPropertyUIDataFloat {
/* IDP_UI_DATA_TYPE_STRING */
typedef struct IDPropertyUIDataString {
- IDPropertyUIData generic_ui_data;
+ IDPropertyUIData base;
char *default_value;
} IDPropertyUIDataString;
/* IDP_UI_DATA_TYPE_ID */
typedef struct IDPropertyUIDataID {
- IDPropertyUIData generic_ui_data;
+ IDPropertyUIData base;
} IDPropertyUIDataID;
typedef struct IDPropertyData {
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index c13a0e9c940..02a52a39881 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -297,7 +297,7 @@ static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
idprop.f = value->value;
IDProperty *property = IDP_New(IDP_FLOAT, &idprop, socket.identifier);
IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property);
- ui_data->generic_ui_data.rna_subtype = value->subtype;
+ ui_data->base.rna_subtype = value->subtype;
ui_data->min = ui_data->soft_min = (double)value->min;
ui_data->max = ui_data->soft_max = (double)value->max;
ui_data->default_value = value->value;
@@ -309,7 +309,7 @@ static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
idprop.i = value->value;
IDProperty *property = IDP_New(IDP_INT, &idprop, socket.identifier);
IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)IDP_ui_data_ensure(property);
- ui_data->generic_ui_data.rna_subtype = value->subtype;
+ ui_data->base.rna_subtype = value->subtype;
ui_data->min = ui_data->soft_min = value->min;
ui_data->max = ui_data->soft_max = value->max;
ui_data->default_value = value->value;
@@ -323,7 +323,7 @@ static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
IDProperty *property = IDP_New(IDP_ARRAY, &idprop, socket.identifier);
copy_v3_v3((float *)IDP_Array(property), value->value);
IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property);
- ui_data->generic_ui_data.rna_subtype = value->subtype;
+ ui_data->base.rna_subtype = value->subtype;
ui_data->min = ui_data->soft_min = (double)value->min;
ui_data->max = ui_data->soft_max = (double)value->max;
ui_data->default_array = (double *)MEM_mallocN(sizeof(double[3]), "mod_prop_default");
diff --git a/source/blender/python/generic/idprop_py_ui_api.c b/source/blender/python/generic/idprop_py_ui_api.c
index cf84fde8145..92cc3b8e1dd 100644
--- a/source/blender/python/generic/idprop_py_ui_api.c
+++ b/source/blender/python/generic/idprop_py_ui_api.c
@@ -103,7 +103,6 @@ static bool idprop_ui_data_update_int_default(IDProperty *idprop,
}
ui_data->default_array_len = len;
- MEM_SAFE_FREE(ui_data->default_array);
ui_data->default_array = new_default_array;
}
else {
@@ -145,10 +144,11 @@ static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObje
}
/* Write to a temporary copy of the UI data in case some part of the parsing fails. */
- IDPropertyUIDataInt ui_data = *(IDPropertyUIDataInt *)idprop->ui_data;
+ IDPropertyUIDataInt *ui_data_orig = (IDPropertyUIDataInt *)idprop->ui_data;
+ IDPropertyUIDataInt ui_data = *ui_data_orig;
- if (!idprop_ui_data_update_base((IDPropertyUIData *)&ui_data, rna_subtype, description)) {
- IDP_ui_data_free_contents((IDPropertyUIData *)&ui_data, IDP_UI_DATA_TYPE_INT);
+ if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) {
+ IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
return false;
}
@@ -178,16 +178,22 @@ static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObje
if (!ELEM(default_value, NULL, Py_None)) {
if (!idprop_ui_data_update_int_default(idprop, &ui_data, default_value)) {
- IDP_ui_data_free_contents((IDPropertyUIData *)&ui_data, IDP_UI_DATA_TYPE_INT);
+ IDP_ui_data_free_unique_contents(
+ &ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base);
return false;
}
}
/* Write back to the proeprty's UI data. */
- *(IDPropertyUIDataInt *)idprop->ui_data = ui_data;
+ IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base);
+ *ui_data_orig = ui_data;
return true;
}
+/**
+ * \note The default value needs special handling because for array IDProperties it can
+ * be a single value or an array, but for non-array properties it can only be a value.
+ */
static bool idprop_ui_data_update_float_default(IDProperty *idprop,
IDPropertyUIDataFloat *ui_data,
PyObject *default_value)
@@ -211,7 +217,6 @@ static bool idprop_ui_data_update_float_default(IDProperty *idprop,
}
ui_data->default_array_len = len;
- MEM_SAFE_FREE(ui_data->default_array);
ui_data->default_array = new_default_array;
}
else
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list