RNA: support passing template arguments to functions
The goal is to allow passing template parameters in the string that is passed to `RNA_def_function` in rna code. This can reduce redundancy (e.g. when used together with #113114). Only "simple" template parameters are supported, i.e. only ones that do not contain a nested `,`. Function names passed to e.g. `RNA_def_property_pointer_funcs` and `RNA_def_property_update` happen to support this already without further changes. Pull Request: https://projects.blender.org/blender/blender/pulls/113121
This commit is contained in:
@@ -3010,6 +3010,25 @@ static void rna_def_property_wrapper_funcs(FILE *f, StructDefRNA *dsrna, Propert
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of template arguments by looking at `<` and `,` characters in the name. More
|
||||||
|
* complex template arguments that contains `,` themselves are not handled yet.
|
||||||
|
*/
|
||||||
|
static int count_template_args(const char *function_name)
|
||||||
|
{
|
||||||
|
BLI_assert(function_name != nullptr);
|
||||||
|
if (!strstr(function_name, "<")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = 1;
|
||||||
|
for (const char *c = function_name; *c; c++) {
|
||||||
|
if (*c == ',') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc)
|
static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc)
|
||||||
{
|
{
|
||||||
StructRNA *srna = dsrna->srna;
|
StructRNA *srna = dsrna->srna;
|
||||||
@@ -3026,7 +3045,10 @@ static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, Functio
|
|||||||
rna_construct_wrapper_function_name(
|
rna_construct_wrapper_function_name(
|
||||||
funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
|
funcname, sizeof(funcname), srna->identifier, func->identifier, "func");
|
||||||
|
|
||||||
fprintf(f, "RNA_EXTERN_C ");
|
/* A function with templates cannot have C linkage. */
|
||||||
|
if (!(dfunc->call && count_template_args(dfunc->call) > 0)) {
|
||||||
|
fprintf(f, "RNA_EXTERN_C ");
|
||||||
|
}
|
||||||
rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 0);
|
rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 0);
|
||||||
|
|
||||||
fprintf(f, "\n{\n");
|
fprintf(f, "\n{\n");
|
||||||
@@ -3785,6 +3807,19 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
|
|||||||
dsrna = rna_find_struct_def(srna);
|
dsrna = rna_find_struct_def(srna);
|
||||||
func = dfunc->func;
|
func = dfunc->func;
|
||||||
|
|
||||||
|
const int template_args_num = dfunc->call ? count_template_args(dfunc->call) : 0;
|
||||||
|
if (!name_override && template_args_num > 0) {
|
||||||
|
/* The template names are called A, B, C, etc. */
|
||||||
|
BLI_assert(template_args_num <= 26);
|
||||||
|
fprintf(f, "template<typename A");
|
||||||
|
char template_name = 'B';
|
||||||
|
for (int i = 0; i < template_args_num - 1; i++) {
|
||||||
|
fprintf(f, ", typename %c", template_name);
|
||||||
|
template_name++;
|
||||||
|
}
|
||||||
|
fprintf(f, "> ");
|
||||||
|
}
|
||||||
|
|
||||||
/* return type */
|
/* return type */
|
||||||
LISTBASE_FOREACH (PropertyDefRNA *, dparm, &dfunc->cont.properties) {
|
LISTBASE_FOREACH (PropertyDefRNA *, dparm, &dfunc->cont.properties) {
|
||||||
if (dparm->prop == func->c_ret) {
|
if (dparm->prop == func->c_ret) {
|
||||||
@@ -3810,7 +3845,15 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
|
|||||||
|
|
||||||
/* function name */
|
/* function name */
|
||||||
if (name_override == nullptr || name_override[0] == '\0') {
|
if (name_override == nullptr || name_override[0] == '\0') {
|
||||||
fprintf(f, "%s(", dfunc->call);
|
/* Here we only need the function name without the template parameters. */
|
||||||
|
const char *template_begin = strstr(dfunc->call, "<");
|
||||||
|
if (template_begin) {
|
||||||
|
const int num_chars = template_begin - dfunc->call;
|
||||||
|
fprintf(f, "%.*s(", num_chars, dfunc->call);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(f, "%s(", dfunc->call);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(f, "%s(", name_override);
|
fprintf(f, "%s(", name_override);
|
||||||
|
|||||||
Reference in New Issue
Block a user