RNA: support automatically mapping string property to char pointer

The goal of this patch is to remove the boilerplate code required to get
a string property that maps to an allocated char pointer in dna.
Previously, one to to provide three callbacks, all of which are not necessary
anymore for a simple string property.

Currently, when an empty string is assigned, the `set` function will always
allocate it as well, instead of assigning `NULL` to the pointer. Some structs
might support `NULL` while others don't, so this is the safer option for now.

Differential Revision: https://developer.blender.org/D10773
This commit is contained in:
Jacques Lucke
2021-03-23 11:46:00 +01:00
parent 4e0fd7fff1
commit eed45b655c
2 changed files with 52 additions and 68 deletions

View File

@@ -705,27 +705,35 @@ static char *rna_def_property_get_func(
rna_print_data_get(f, dp);
if (!(prop->flag & PROP_NEVER_NULL)) {
if (dp->dnapointerlevel == 1) {
/* Handle allocated char pointer properties. */
fprintf(f, " if (data->%s == NULL) {\n", dp->dnaname);
fprintf(f, " *value = '\\0';\n");
fprintf(f, " return;\n");
fprintf(f, " }\n");
}
if (sprop->maxlength) {
fprintf(f,
" %s(value, data->%s, %d);\n",
string_copy_func,
dp->dnaname,
sprop->maxlength);
}
else {
fprintf(f,
" %s(value, data->%s, sizeof(data->%s));\n",
" %s(value, data->%s, strlen(data->%s) + 1);\n",
string_copy_func,
dp->dnaname,
dp->dnaname);
}
else {
/* Handle char array properties. */
if (sprop->maxlength) {
fprintf(f,
" %s(value, data->%s, %d);\n",
string_copy_func,
dp->dnaname,
sprop->maxlength);
}
else {
fprintf(f,
" %s(value, data->%s, sizeof(data->%s));\n",
string_copy_func,
dp->dnaname,
dp->dnaname);
}
}
}
fprintf(f, "}\n\n");
break;
@@ -1046,25 +1054,30 @@ static char *rna_def_property_set_func(
rna_print_data_get(f, dp);
if (!(prop->flag & PROP_NEVER_NULL)) {
fprintf(f, " if (data->%s == NULL) {\n", dp->dnaname);
fprintf(f, " return;\n");
fprintf(f, " }\n");
}
if (sprop->maxlength) {
fprintf(f,
" %s(data->%s, value, %d);\n",
string_copy_func,
dp->dnaname,
sprop->maxlength);
if (dp->dnapointerlevel == 1) {
/* Handle allocated char pointer properties. */
fprintf(
f, " if (data->%s != NULL) { MEM_freeN(data->%s); }\n", dp->dnaname, dp->dnaname);
fprintf(f, " const int length = strlen(value);\n");
fprintf(f, " data->%s = MEM_mallocN(length + 1, __func__);\n", dp->dnaname);
fprintf(f, " %s(data->%s, value, length + 1);\n", string_copy_func, dp->dnaname);
}
else {
fprintf(f,
" %s(data->%s, value, sizeof(data->%s));\n",
string_copy_func,
dp->dnaname,
dp->dnaname);
/* Handle char array properties. */
if (sprop->maxlength) {
fprintf(f,
" %s(data->%s, value, %d);\n",
string_copy_func,
dp->dnaname,
sprop->maxlength);
}
else {
fprintf(f,
" %s(data->%s, value, sizeof(data->%s));\n",
string_copy_func,
dp->dnaname,
dp->dnaname);
}
}
}
fprintf(f, "}\n\n");
@@ -1285,10 +1298,17 @@ static char *rna_def_property_length_func(
}
else {
rna_print_data_get(f, dp);
if (!(prop->flag & PROP_NEVER_NULL)) {
fprintf(f, " if (data->%s == NULL) { return 0; }\n", dp->dnaname);
if (dp->dnapointerlevel == 1) {
/* Handle allocated char pointer properties. */
fprintf(f,
" return (data->%s == NULL) ? 0 : strlen(data->%s);\n",
dp->dnaname,
dp->dnaname);
}
else {
/* Handle char array properties. */
fprintf(f, " return strlen(data->%s);\n", dp->dnaname);
}
fprintf(f, " return strlen(data->%s);\n", dp->dnaname);
}
fprintf(f, "}\n\n");
}

View File

@@ -4290,38 +4290,6 @@ void rna_ShaderNodePointDensity_density_minmax(bNode *self,
RE_point_density_minmax(depsgraph, pd, r_min, r_max);
}
static void rna_NodeInputString_string_get(PointerRNA *ptr, char *value)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
strcpy(value, (storage->string) ? storage->string : "");
}
static int rna_NodeInputString_string_length(PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
return (storage->string) ? strlen(storage->string) : 0;
}
static void rna_NodeInputString_string_set(PointerRNA *ptr, const char *value)
{
bNode *node = (bNode *)ptr->data;
NodeInputString *storage = node->storage;
if (storage->string) {
MEM_freeN(storage->string);
}
if (value && value[0]) {
storage->string = BLI_strdup(value);
}
else {
storage->string = NULL;
}
}
#else
static const EnumPropertyItem prop_image_layer_items[] = {
@@ -4744,10 +4712,6 @@ static void def_fn_input_string(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeInputString", "storage");
prop = RNA_def_property(srna, "string", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_NodeInputString_string_get",
"rna_NodeInputString_string_length",
"rna_NodeInputString_string_set");
RNA_def_property_ui_text(prop, "String", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}