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)
|
||||
{
|
||||
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(
|
||||
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);
|
||||
|
||||
fprintf(f, "\n{\n");
|
||||
@@ -3785,6 +3807,19 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
|
||||
dsrna = rna_find_struct_def(srna);
|
||||
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 */
|
||||
LISTBASE_FOREACH (PropertyDefRNA *, dparm, &dfunc->cont.properties) {
|
||||
if (dparm->prop == func->c_ret) {
|
||||
@@ -3810,7 +3845,15 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
|
||||
|
||||
/* function name */
|
||||
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 {
|
||||
fprintf(f, "%s(", name_override);
|
||||
|
||||
Reference in New Issue
Block a user