diff options
Diffstat (limited to 'source/blender/makesrna/intern/makesrna.c')
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 886 |
1 files changed, 778 insertions, 108 deletions
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index af857b61e26..7a3bb230a78 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -61,7 +61,6 @@ /* Replace if different */ #define TMP_EXT ".tmp" - /* copied from BLI_file_older */ #include <sys/stat.h> static int file_older(const char *file1, const char *file2) @@ -76,6 +75,24 @@ static int file_older(const char *file1, const char *file2) } static const char *makesrna_path = NULL; +/* forward declarations */ +static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc, + const char *name_override, int close_prototype); + +/* helpers */ +#define WRITE_COMMA \ + { \ + if (!first) \ + fprintf(f, ", "); \ + first = 0; \ + } (void)0 + +#define WRITE_PARAM(param) \ + { \ + WRITE_COMMA; \ + fprintf(f, param); \ + } + static int replace_if_different(char *tmpfile, const char *dep_files[]) { /* return 0; *//* use for testing had edited rna */ @@ -212,6 +229,8 @@ static const char *rna_safe_id(const char *id) return "default_value"; else if (strcmp(id, "operator") == 0) return "operator_value"; + else if (strcmp(id, "new") == 0) + return "create"; return id; } @@ -322,13 +341,26 @@ static void rna_print_id_get(FILE *f, PropertyDefRNA *UNUSED(dp)) fprintf(f, " ID *id= ptr->id.data;\n"); } +static void rna_construct_function_name(char *buffer, int size, const char *structname, const char *propname, const char *type) +{ + snprintf(buffer, size, "%s_%s_%s", structname, propname, type); +} + +static void rna_construct_wrapper_function_name(char *buffer, int size, const char *structname, const char *propname, const char *type) +{ + if (type == NULL || type[0] == '\0') + snprintf(buffer, size, "%s_%s", structname, propname); + else + snprintf(buffer, size, "%s_%s_%s", structname, propname, type); +} + static char *rna_alloc_function_name(const char *structname, const char *propname, const char *type) { AllocDefRNA *alloc; char buffer[2048]; char *result; - snprintf(buffer, sizeof(buffer), "%s_%s_%s", structname, propname, type); + rna_construct_function_name(buffer, sizeof(buffer), structname, propname, type); result = MEM_callocN(sizeof(char) * strlen(buffer) + 1, "rna_alloc_function_name"); strcpy(result, buffer); @@ -627,17 +659,17 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr "get_length"); fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); - fprintf(f, " for (i=0; i<len; i++) {\n"); + fprintf(f, " for (i=0; i < len; i++) {\n"); MEM_freeN(lenfunc); } else { fprintf(f, " int i;\n\n"); - fprintf(f, " for (i=0; i<%u; i++) {\n", prop->totarraylength); + fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength); } if (dp->dnaarraylength == 1) { if (prop->type == PROP_BOOLEAN && dp->booleanbit) { - fprintf(f, " values[i] = %s((data->%s & (%d<<i)) != 0);\n", + fprintf(f, " values[i] = %s((data->%s & (%d << i)) != 0);\n", (dp->booleannegative) ? "!" : "", dp->dnaname, dp->booleanbit); } else { @@ -653,7 +685,7 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr fprintf(f, ") != 0);\n"); } else if (rna_color_quantize(prop, dp)) { - fprintf(f, " values[i] = (%s)(data->%s[i]*(1.0f/255.0f));\n", + fprintf(f, " values[i] = (%s)(data->%s[i]*(1.0f / 255.0f));\n", rna_type_type(prop), dp->dnaname); } else if (dp->dnatype) { @@ -878,20 +910,20 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n"); fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc); rna_clamp_value_range(f, prop); - fprintf(f, " for (i=0; i<len; i++) {\n"); + fprintf(f, " for (i=0; i < len; i++) {\n"); MEM_freeN(lenfunc); } else { fprintf(f, " int i;\n\n"); rna_clamp_value_range(f, prop); - fprintf(f, " for (i=0; i<%u; i++) {\n", prop->totarraylength); + fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength); } if (dp->dnaarraylength == 1) { if (prop->type == PROP_BOOLEAN && dp->booleanbit) { fprintf(f, " if (%svalues[i]) data->%s |= (%d<<i);\n", (dp->booleannegative) ? "!" : "", dp->dnaname, dp->booleanbit); - fprintf(f, " else data->%s &= ~(%d<<i);\n", dp->dnaname, dp->booleanbit); + fprintf(f, " else data->%s &= ~(%d << i);\n", dp->dnaname, dp->booleanbit); } else { fprintf(f, " (&data->%s)[i] = %s", dp->dnaname, (dp->booleannegative) ? "!" : ""); @@ -1015,9 +1047,9 @@ static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA else { rna_print_data_get(f, dp); if (dp->dnalengthname) - fprintf(f, " return (data->%s == NULL)? 0: data->%s;\n", dp->dnaname, dp->dnalengthname); + fprintf(f, " return (data->%s == NULL) ? 0 : data->%s;\n", dp->dnaname, dp->dnalengthname); else - fprintf(f, " return (data->%s == NULL)? 0: %d;\n", dp->dnaname, dp->dnalengthfixed); + fprintf(f, " return (data->%s == NULL) ? 0 : %d;\n", dp->dnaname, dp->dnalengthfixed); } fprintf(f, "}\n\n"); } @@ -1102,8 +1134,8 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property return NULL; /* only supported in case of standard next functions */ - if (strcmp(nextfunc, "rna_iterator_array_next") == 0) ; - else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) ; + if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {} + else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {} else return NULL; } @@ -1372,9 +1404,12 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; const char *nextfunc = (const char *)cprop->next; - if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) ; - else if (dp->dnalengthname || dp->dnalengthfixed) + if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) { + /* pass */ + } + else if (dp->dnalengthname || dp->dnalengthfixed) { cprop->length = (void *)rna_def_property_length_func(f, srna, prop, dp, (const char *)cprop->length); + } /* test if we can allow raw array access, if it is using our standard * array get/next function, we can be sure it is an actual array */ @@ -1437,15 +1472,15 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR { if (!prop->arraydimension) { fprintf(f, "int %sget(PointerRNA *ptr);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func); } else if (prop->arraydimension && prop->totarraylength) { fprintf(f, "void %sget(PointerRNA *ptr, int values[%u]);\n", func, prop->totarraylength); - /*fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->arraylength); */ + fprintf(f, "void %sset(PointerRNA *ptr, const int values[%d]);\n", func, prop->totarraylength); } else { fprintf(f, "void %sget(PointerRNA *ptr, int values[]);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, const int values[]);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, const int values[]);\n", func); } break; } @@ -1453,15 +1488,15 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR { if (!prop->arraydimension) { fprintf(f, "float %sget(PointerRNA *ptr);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, float value);\n", func); } else if (prop->arraydimension && prop->totarraylength) { fprintf(f, "void %sget(PointerRNA *ptr, float values[%u]);\n", func, prop->totarraylength); - /*fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->arraylength); */ + fprintf(f, "void %sset(PointerRNA *ptr, const float values[%d]);\n", func, prop->totarraylength); } else { fprintf(f, "void %sget(PointerRNA *ptr, float values[]);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, const float values[]);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, const float values[]);", func); } break; } @@ -1482,7 +1517,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR } fprintf(f, "int %sget(PointerRNA *ptr);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, int value);\n", func); break; } @@ -1496,7 +1531,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR fprintf(f, "void %sget(PointerRNA *ptr, char *value);\n", func); fprintf(f, "int %slength(PointerRNA *ptr);\n", func); - /*fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func); */ + fprintf(f, "void %sset(PointerRNA *ptr, const char *value);\n", func); break; } @@ -1508,19 +1543,38 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR } case PROP_COLLECTION: { + CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; fprintf(f, "void %sbegin(CollectionPropertyIterator *iter, PointerRNA *ptr);\n", func); fprintf(f, "void %snext(CollectionPropertyIterator *iter);\n", func); fprintf(f, "void %send(CollectionPropertyIterator *iter);\n", func); - /*fprintf(f, "int %slength(PointerRNA *ptr);\n", func); */ - /*fprintf(f, "void %slookup_int(PointerRNA *ptr, int key, StructRNA **type);\n", func); */ - /*fprintf(f, "void %slookup_string(PointerRNA *ptr, const char *key, StructRNA **type);\n", func); */ + if (cprop->length) + fprintf(f, "int %slength(PointerRNA *ptr);\n", func); + if (cprop->lookupint) + fprintf(f, "int %slookup_int(PointerRNA *ptr, int key, PointerRNA *r_ptr);\n", func); + if (cprop->lookupstring) + fprintf(f, "int %slookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr);\n", func); break; } } + if (prop->getlength) { + char funcname[2048]; + rna_construct_wrapper_function_name(funcname, sizeof(funcname), srna->identifier, prop->identifier, "get_length"); + fprintf(f, "int %s(PointerRNA *ptr, int *arraylen);\n", funcname); + } + fprintf(f, "\n"); } +static void rna_def_function_funcs_header(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc) +{ + FunctionRNA *func = dfunc->func; + char funcname[2048]; + + rna_construct_wrapper_function_name(funcname, sizeof(funcname), srna->identifier, func->identifier, NULL); + rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 1); +} + static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; @@ -1540,26 +1594,50 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property switch (prop->type) { case PROP_BOOLEAN: { - if (!prop->arraydimension) - fprintf(f, "\tinline bool %s(void);", rna_safe_id(prop->identifier)); - else if (prop->totarraylength) - fprintf(f, "\tinline Array<int, %u> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier)); + if (!prop->arraydimension) { + fprintf(f, "\tinline bool %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int value);", rna_safe_id(prop->identifier)); + } + else if (prop->totarraylength) { + fprintf(f, "\tinline Array<int, %u> %s(void);\n", prop->totarraylength, rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int values[%u]);", rna_safe_id(prop->identifier), prop->totarraylength); + } + else if (prop->getlength) { + fprintf(f, "\tinline DynamicArray<int> %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int values[]);", rna_safe_id(prop->identifier)); + } break; } case PROP_INT: { - if (!prop->arraydimension) - fprintf(f, "\tinline int %s(void);", rna_safe_id(prop->identifier)); - else if (prop->totarraylength) - fprintf(f, "\tinline Array<int, %u> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier)); + if (!prop->arraydimension) { + fprintf(f, "\tinline int %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int value);", rna_safe_id(prop->identifier)); + } + else if (prop->totarraylength) { + fprintf(f, "\tinline Array<int, %u> %s(void);\n", prop->totarraylength, rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int values[%u]);", rna_safe_id(prop->identifier), prop->totarraylength); + } + else if (prop->getlength) { + fprintf(f, "\tinline DynamicArray<int> %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(int values[]);", rna_safe_id(prop->identifier)); + } break; } case PROP_FLOAT: { - if (!prop->arraydimension) - fprintf(f, "\tinline float %s(void);", rna_safe_id(prop->identifier)); - else if (prop->totarraylength) - fprintf(f, "\tinline Array<float, %u> %s(void);", prop->totarraylength, rna_safe_id(prop->identifier)); + if (!prop->arraydimension) { + fprintf(f, "\tinline float %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(float value);", rna_safe_id(prop->identifier)); + } + else if (prop->totarraylength) { + fprintf(f, "\tinline Array<float, %u> %s(void);\n", prop->totarraylength, rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(float values[%u]);", rna_safe_id(prop->identifier), prop->totarraylength); + } + else if (prop->getlength) { + fprintf(f, "\tinline DynamicArray<float> %s(void);\n", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(float values[]);", rna_safe_id(prop->identifier)); + } break; } case PROP_ENUM: @@ -1578,12 +1656,14 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property fprintf(f, "\t};\n"); } - fprintf(f, "\tinline %s_enum %s(void);", rna_safe_id(prop->identifier), rna_safe_id(prop->identifier)); + fprintf(f, "\tinline %s_enum %s(void);\n", rna_safe_id(prop->identifier), rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(%s_enum value);", rna_safe_id(prop->identifier), rna_safe_id(prop->identifier)); break; } case PROP_STRING: { fprintf(f, "\tinline std::string %s(void);", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(const std::string& value);", rna_safe_id(prop->identifier)); break; } case PROP_POINTER: @@ -1599,13 +1679,19 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property case PROP_COLLECTION: { CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop; + const char *collection_funcs = "DefaultCollectionFunctions"; + + if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna) + collection_funcs = (char*)cprop->property.srna; if (cprop->item_type) - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (const char *)cprop->item_type, srna->identifier, - rna_safe_id(prop->identifier)); + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier, + rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"), + (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); else - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, - rna_safe_id(prop->identifier)); + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, "UnknownType", srna->identifier, + rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"), + (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); break; } } @@ -1613,6 +1699,96 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property fprintf(f, "\n"); } +static const char *rna_parameter_type_cpp_name(PropertyRNA *prop) +{ + if (prop->type == PROP_POINTER) { + /* for cpp api we need to use RNA structures names for pointers */ + PointerPropertyRNA *pprop = (PointerPropertyRNA *) prop; + + return (const char *) pprop->type; + } + else { + return rna_parameter_type_name(prop); + } +} + +static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc, + const char *namespace, int close_prototype) +{ + PropertyDefRNA *dp; + FunctionRNA *func = dfunc->func; + + int first = 1; + const char *retval_type = "void"; + + if (func->c_ret) { + dp = rna_find_parameter_def(func->c_ret); + retval_type = rna_parameter_type_cpp_name(dp->prop); + } + + if (namespace && namespace[0]) + fprintf(f, "\tinline %s %s::%s(", retval_type, namespace, rna_safe_id(func->identifier)); + else + fprintf(f, "\tinline %s %s(", retval_type, rna_safe_id(func->identifier)); + + if (func->flag & FUNC_USE_MAIN) + WRITE_PARAM("void *main"); + + if (func->flag & FUNC_USE_CONTEXT) + WRITE_PARAM("Context C"); + + for (dp = dfunc->cont.properties.first; dp; dp = dp->next) { + int type, flag, pout; + const char *ptrstr; + + if (dp->prop == func->c_ret) + continue; + + type = dp->prop->type; + flag = dp->prop->flag; + pout = (flag & PROP_OUTPUT); + + if (type == PROP_POINTER) + ptrstr = ""; + else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) + ptrstr = "*"; + else if (type == PROP_POINTER || dp->prop->arraydimension) + ptrstr = "*"; + else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) + ptrstr = ""; + else + ptrstr = pout ? "*" : ""; + + WRITE_COMMA; + + if (flag & PROP_DYNAMIC) + fprintf(f, "int %s%s_len, ", (flag & PROP_OUTPUT) ? "*" : "", dp->prop->identifier); + + if (!(flag & PROP_DYNAMIC) && dp->prop->arraydimension) + fprintf(f, "%s %s[%u]", rna_parameter_type_cpp_name(dp->prop), + rna_safe_id(dp->prop->identifier), dp->prop->totarraylength); + else + fprintf(f, "%s %s%s", rna_parameter_type_cpp_name(dp->prop), + ptrstr, rna_safe_id(dp->prop->identifier)); + } + + fprintf(f, ")"); + if (close_prototype) + fprintf(f, ";\n"); +} + +static void rna_def_struct_function_header_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc) +{ + FunctionRNA *func = dfunc->func; + + if (!dfunc->call) + return; + + fprintf(f, "\n\t/* %s */\n", func->description); + + rna_def_struct_function_prototype_cpp(f, srna, dfunc, NULL, 1); +} + static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDefRNA *dp) { PropertyRNA *prop; @@ -1630,6 +1806,9 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe else if (prop->totarraylength) fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %u, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier)); + else if (prop->getlength) + fprintf(f, "\tBOOLEAN_DYNAMIC_ARRAY_PROPERTY(%s, %s)", srna->identifier, + rna_safe_id(prop->identifier)); break; } case PROP_INT: @@ -1639,6 +1818,9 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe else if (prop->totarraylength) fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %u, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier)); + else if (prop->getlength) + fprintf(f, "\tINT_DYNAMIC_ARRAY_PROPERTY(%s, %s)", srna->identifier, + rna_safe_id(prop->identifier)); break; } case PROP_FLOAT: @@ -1648,6 +1830,9 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe else if (prop->totarraylength) fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %u, %s)", srna->identifier, prop->totarraylength, rna_safe_id(prop->identifier)); + else if (prop->getlength) + fprintf(f, "\tFLOAT_DYNAMIC_ARRAY_PROPERTY(%s, %s)", srna->identifier, + rna_safe_id(prop->identifier)); break; } case PROP_ENUM: @@ -1680,10 +1865,13 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop; if (cprop->type) - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (const char *)cprop->type, srna->identifier, - prop->identifier); + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", (const char *)cprop->type, srna->identifier, + prop->identifier, (cprop->length ? "TRUE" : "FALSE"), + (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); else - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier); + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", "UnknownType", srna->identifier, + prop->identifier, (cprop->length ? "TRUE" : "FALSE"), + (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); #endif break; } @@ -1692,6 +1880,181 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe fprintf(f, "\n"); } +static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc) +{ + PropertyDefRNA *dp; + StructDefRNA *dsrna; + FunctionRNA *func = dfunc->func; + char funcname[2048]; + + int first = 1; + + rna_construct_wrapper_function_name(funcname, sizeof(funcname), srna->identifier, func->identifier, NULL); + + fprintf(f, "%s(", funcname); + + dsrna = rna_find_struct_def(srna); + + if (func->flag & FUNC_USE_SELF_ID) + WRITE_PARAM("(::ID *) ptr.id.data"); + + if ((func->flag & FUNC_NO_SELF) == 0) { + WRITE_COMMA; + if (dsrna->dnaname) fprintf(f, "(::%s *) this->ptr.data", dsrna->dnaname); + else fprintf(f, "(::%s *) this->ptr.data", srna->identifier); + } + + if (func->flag & FUNC_USE_MAIN) + WRITE_PARAM("(::Main *) main"); + + if (func->flag & FUNC_USE_CONTEXT) + WRITE_PARAM("(::bContext *) C.ptr.data"); + + if (func->flag & FUNC_USE_REPORTS) + WRITE_PARAM("NULL"); + + dp = dfunc->cont.properties.first; + for (; dp; dp = dp->next) { + if (dp->prop == func->c_ret) + continue; + + WRITE_COMMA; + + if (dp->prop->flag & PROP_DYNAMIC) + fprintf(f, "%s_len, ", dp->prop->identifier); + + if (dp->prop->type == PROP_POINTER) + if ((dp->prop->flag & PROP_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP)) + fprintf(f, "(::%s *) &%s.ptr", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier)); + else + fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier)); + else + fprintf(f, "%s", rna_safe_id(dp->prop->identifier)); + } + + fprintf(f, ");\n"); +} + +static void rna_def_struct_function_impl_cpp(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc) +{ + PropertyDefRNA *dp; + PointerPropertyRNA *pprop; + + FunctionRNA *func = dfunc->func; + + if (!dfunc->call) + return; + + rna_def_struct_function_prototype_cpp(f, srna, dfunc, srna->identifier, 0); + + fprintf(f, " {\n"); + + if (func->c_ret) { + dp = rna_find_parameter_def(func->c_ret); + + if (dp->prop->type == PROP_POINTER) { + pprop = (PointerPropertyRNA *) dp->prop; + + fprintf(f, "\t\tPointerRNA result;\n"); + + if ((dp->prop->flag & PROP_RNAPTR) == 0) { + StructRNA *ret_srna = rna_find_struct((const char *) pprop->type); + fprintf(f, "\t\t::%s *retdata = ", rna_parameter_type_name(dp->prop)); + rna_def_struct_function_call_impl_cpp(f, srna, dfunc); + if (ret_srna->flag & STRUCT_ID) + fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &result);\n"); + else + fprintf(f, "\t\tRNA_pointer_create((::ID *) ptr.id.data, &RNA_%s, retdata, &result);\n", (const char *) pprop->type); + } + else { + fprintf(f, "\t\tresult = "); + rna_def_struct_function_call_impl_cpp(f, srna, dfunc); + } + + fprintf(f, "\t\treturn %s(result);\n", (const char *) pprop->type); + } + else { + fprintf(f, "\t\treturn "); + rna_def_struct_function_call_impl_cpp(f, srna, dfunc); + } + } + else { + fprintf(f, "\t\t"); + rna_def_struct_function_call_impl_cpp(f, srna, dfunc); + } + + fprintf(f, "\t}\n\n"); +} + +static void rna_def_property_wrapper_funcs(FILE *f, StructDefRNA *dsrna, PropertyDefRNA *dp) +{ + if (dp->prop->getlength) { + char funcname[2048]; + rna_construct_wrapper_function_name(funcname, sizeof(funcname), dsrna->srna->identifier, dp->prop->identifier, "get_length"); + fprintf(f, "int %s(PointerRNA *ptr, int *arraylen)\n", funcname); + fprintf(f, "{\n"); + fprintf(f, "\treturn %s(ptr, arraylen);\n", rna_function_string(dp->prop->getlength)); + fprintf(f, "}\n\n"); + } +} + +static void rna_def_function_wrapper_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc) +{ + StructRNA *srna = dsrna->srna; + FunctionRNA *func = dfunc->func; + PropertyDefRNA *dparm; + + int first; + char funcname[2048]; + + if (!dfunc->call) + return; + + rna_construct_wrapper_function_name(funcname, sizeof(funcname), srna->identifier, func->identifier, NULL); + + rna_generate_static_parameter_prototypes(f, srna, dfunc, funcname, 0); + + fprintf(f, "\n{\n"); + + if (func->c_ret) + fprintf(f, "\treturn %s(", dfunc->call); + else + fprintf(f, "\t%s(", dfunc->call); + + first = 1; + + if (func->flag & FUNC_USE_SELF_ID) + WRITE_PARAM("_selfid"); + + if ((func->flag & FUNC_NO_SELF) == 0) + WRITE_PARAM("_self"); + + if (func->flag & FUNC_USE_MAIN) + WRITE_PARAM("bmain"); + + if (func->flag & FUNC_USE_CONTEXT) + WRITE_PARAM("C"); + + if (func->flag & FUNC_USE_REPORTS) + WRITE_PARAM("reports"); + + dparm = dfunc->cont.properties.first; + for (; dparm; dparm = dparm->next) { + if (dparm->prop == func->c_ret) + continue; + + WRITE_COMMA; + + if (dparm->prop->flag & PROP_DYNAMIC) + fprintf(f, "%s_len, %s", dparm->prop->identifier, dparm->prop->identifier); + else + fprintf(f, "%s", rna_safe_id(dparm->prop->identifier)); + } + + fprintf(f, ");\n"); + fprintf(f, "}\n\n"); +} + static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA *dfunc) { StructRNA *srna; @@ -1741,6 +2104,8 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA /* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */ else if (type == PROP_POINTER || dparm->prop->arraydimension) ptrstr = "*"; + else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) + ptrstr = "*"; /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, * but type name for string props is already char*, so leave empty */ else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) @@ -1792,6 +2157,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA ptrstr = "**"; valstr = "*"; } + else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) { + ptrstr = "**"; + valstr = "*"; + } else if (type == PROP_POINTER || dparm->prop->arraydimension) { ptrstr = "*"; valstr = ""; @@ -1991,6 +2360,7 @@ static const char *rna_property_subtypename(PropertySubType type) case PROP_COORDS: return "PROP_COORDS"; case PROP_LAYER: return "PROP_LAYER"; case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER"; + case PROP_PASSWORD: return "PROP_PASSWORD"; default: { /* in case we don't have a type preset that includes the subtype */ if (RNA_SUBTYPE_UNIT(type)) { @@ -2107,7 +2477,7 @@ static void rna_generate_function_prototypes(BlenderRNA *brna, StructRNA *srna, fprintf(f, "\n"); } -static void rna_generate_static_parameter_prototypes(BlenderRNA *UNUSED(brna), StructRNA *srna, FunctionDefRNA *dfunc, FILE *f) +static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, FunctionDefRNA *dfunc, const char *name_override, int close_prototype) { FunctionRNA *func; PropertyDefRNA *dparm; @@ -2138,7 +2508,10 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *UNUSED(brna), S fprintf(f, "void "); /* function name */ - fprintf(f, "%s(", dfunc->call); + if (name_override == NULL || name_override[0] == '\0') + fprintf(f, "%s(", dfunc->call); + else + fprintf(f, "%s(", name_override); first = 1; @@ -2147,7 +2520,7 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *UNUSED(brna), S fprintf(f, "struct ID *_selfid"); first = 0; } - + if ((func->flag & FUNC_NO_SELF) == 0) { if (!first) fprintf(f, ", "); if (dsrna->dnaname) fprintf(f, "struct %s *_self", dsrna->dnaname); @@ -2200,17 +2573,19 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *UNUSED(brna), S if (!(flag & PROP_DYNAMIC) && dparm->prop->arraydimension) fprintf(f, "%s%s %s[%u]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), - dparm->prop->identifier, dparm->prop->totarraylength); + rna_safe_id(dparm->prop->identifier), dparm->prop->totarraylength); else fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), - ptrstr, dparm->prop->identifier); + ptrstr, rna_safe_id(dparm->prop->identifier)); } - fprintf(f, ");\n"); + fprintf(f, ")"); + if (close_prototype) + fprintf(f, ";\n"); } -static void rna_generate_static_function_prototypes(BlenderRNA *brna, StructRNA *srna, FILE *f) +static void rna_generate_static_function_prototypes(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE *f) { FunctionRNA *func; FunctionDefRNA *dfunc; @@ -2225,7 +2600,50 @@ static void rna_generate_static_function_prototypes(BlenderRNA *brna, StructRNA first = 0; } - rna_generate_static_parameter_prototypes(brna, srna, dfunc, f); + rna_generate_static_parameter_prototypes(f, srna, dfunc, NULL, 1); + } + } + + fprintf(f, "\n"); +} + +static void rna_generate_struct_prototypes(FILE *f) +{ + StructDefRNA *ds; + PropertyDefRNA *dp; + FunctionDefRNA *dfunc; + const char *structures[2048]; + int all_structures = 0; + + /* structures definitions */ + for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) { + if (dfunc->call) { + for (dp = dfunc->cont.properties.first; dp; dp = dp->next) { + if (dp->prop->type == PROP_POINTER) { + int a, found = 0; + const char *struct_name = rna_parameter_type_name(dp->prop); + + for (a = 0; a < all_structures; a++) { + if (strcmp(struct_name, structures[a]) == 0) { + found = 1; + break; + } + } + + if (found == 0) { + fprintf(f, "struct %s;\n", struct_name); + + if (all_structures >= sizeof(structures) / sizeof(structures[0])) { + printf("Array size to store all structures names is too small\n"); + exit(1); + } + + structures[all_structures++] = struct_name; + } + } + } + } } } @@ -2791,8 +3209,13 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { if (!filename || ds->filename == filename) { - for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) + for (dp = ds->cont.properties.first; dp; dp = dp->next) + rna_def_property_wrapper_funcs(f, ds, dp); + + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) { + rna_def_function_wrapper_funcs(f, ds, dfunc); rna_def_function_funcs(f, ds, dfunc); + } rna_generate_static_function_prototypes(brna, ds->srna, f); } @@ -2816,6 +3239,7 @@ static void rna_generate_header(BlenderRNA *UNUSED(brna), FILE *f) StructDefRNA *ds; PropertyDefRNA *dp; StructRNA *srna; + FunctionDefRNA *dfunc; fprintf(f, "\n#ifndef __RNA_BLENDER_H__\n"); fprintf(f, "#define __RNA_BLENDER_H__\n\n"); @@ -2853,6 +3277,9 @@ static void rna_generate_header(BlenderRNA *UNUSED(brna), FILE *f) for (dp = ds->cont.properties.first; dp; dp = dp->next) rna_def_property_funcs_header(f, ds->srna, dp); + + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) + rna_def_function_funcs_header(f, ds->srna, dfunc); } fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n"); @@ -2868,43 +3295,141 @@ static const char *cpp_classes = "" "namespace BL {\n" "\n" "#define BOOLEAN_PROPERTY(sname, identifier) \\\n" -" inline bool sname::identifier(void) { return sname##_##identifier##_get(&ptr)? true: false; }\n" +" inline bool sname::identifier(void) { return sname##_##identifier##_get(&ptr)? true: false; } \\\n" +" inline void sname::identifier(int value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n" " inline Array<int,size> sname::identifier(void) \\\n" -" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n" +" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" +" inline void sname::identifier(int values[size]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" +"\n" +"#define BOOLEAN_DYNAMIC_ARRAY_PROPERTY(sname, identifier) \\\n" +" inline DynamicArray<int> sname::identifier(void) { \\\n" +" int arraylen[3]; \\\n" +" int len = sname##_##identifier##_get_length(&ptr, arraylen); \\\n" +" DynamicArray<int> ar(len); \\\n" +" sname##_##identifier##_get(&ptr, ar.data); \\\n" +" return ar; } \\\n" +" inline void sname::identifier(int values[]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" "\n" "#define INT_PROPERTY(sname, identifier) \\\n" -" inline int sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n" +" inline int sname::identifier(void) { return sname##_##identifier##_get(&ptr); } \\\n" +" inline void sname::identifier(int value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define INT_ARRAY_PROPERTY(sname, size, identifier) \\\n" " inline Array<int,size> sname::identifier(void) \\\n" -" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n" +" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" +" inline void sname::identifier(int values[size]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" +"\n" +"#define INT_DYNAMIC_ARRAY_PROPERTY(sname, identifier) \\\n" +" inline DynamicArray<int> sname::identifier(void) { \\\n" +" int arraylen[3]; \\\n" +" int len = sname##_##identifier##_get_length(&ptr, arraylen); \\\n" +" DynamicArray<int> ar(len); \\\n" +" sname##_##identifier##_get(&ptr, ar.data); \\\n" +" return ar; } \\\n" +" inline void sname::identifier(int values[]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" "\n" "#define FLOAT_PROPERTY(sname, identifier) \\\n" -" inline float sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n" +" inline float sname::identifier(void) { return sname##_##identifier##_get(&ptr); } \\\n" +" inline void sname::identifier(float value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define FLOAT_ARRAY_PROPERTY(sname, size, identifier) \\\n" " inline Array<float,size> sname::identifier(void) \\\n" -" { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n" +" { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; } \\\n" +" inline void sname::identifier(float values[size]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" +"\n" +"#define FLOAT_DYNAMIC_ARRAY_PROPERTY(sname, identifier) \\\n" +" inline DynamicArray<float> sname::identifier(void) { \\\n" +" int arraylen[3]; \\\n" +" int len = sname##_##identifier##_get_length(&ptr, arraylen); \\\n" +" DynamicArray<float> ar(len); \\\n" +" sname##_##identifier##_get(&ptr, ar.data); \\\n" +" return ar; } \\\n" +" inline void sname::identifier(float values[]) \\\n" +" { sname##_##identifier##_set(&ptr, values); } \\\n" "\n" "#define ENUM_PROPERTY(type, sname, identifier) \\\n" -" inline sname::type sname::identifier(void) { return (type)sname##_##identifier##_get(&ptr); }\n" +" inline sname::type sname::identifier(void) { return (type)sname##_##identifier##_get(&ptr); } \\\n" +" inline void sname::identifier(sname::type value) { sname##_##identifier##_set(&ptr, value); }\n" "\n" "#define STRING_PROPERTY(sname, identifier) \\\n" " inline std::string sname::identifier(void) { \\\n" " int len= sname##_##identifier##_length(&ptr); \\\n" " std::string str; str.resize(len); \\\n" " sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n" +" inline void sname::identifier(const std::string& value) { \\\n" +" sname##_##identifier##_set(&ptr, value.c_str()); } \\\n" "\n" "#define POINTER_PROPERTY(type, sname, identifier) \\\n" " inline type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n" "\n" -"#define COLLECTION_PROPERTY(type, sname, identifier) \\\n" +"#define COLLECTION_PROPERTY_LENGTH_FALSE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_length_wrap(PointerRNA *ptr) \\\n" +" { \\\n" +" CollectionPropertyIterator iter; \\\n" +" int length = 0; \\\n" +" sname##_##identifier##_begin(&iter, ptr); \\\n" +" while (iter.valid) { \\\n" +" sname##_##identifier##_next(&iter); \\\n" +" ++length; \\\n" +" } \\\n" +" sname##_##identifier##_end(&iter); \\\n" +" return length; \\\n" +" } \n" +"#define COLLECTION_PROPERTY_LENGTH_TRUE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_length_wrap(PointerRNA *ptr) \\\n" +" { return sname##_##identifier##_length(ptr); } \n" +"\n" +"#define COLLECTION_PROPERTY_LOOKUP_INT_FALSE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n" +" { \\\n" +" CollectionPropertyIterator iter; \\\n" +" int i = 0, found = 0; \\\n" +" sname##_##identifier##_begin(&iter, ptr); \\\n" +" while (iter.valid) { \\\n" +" if (i == key) { \\\n" +" *r_ptr = iter.ptr; \\\n" +" found = 1; \\\n" +" break; \\\n" +" } \\\n" +" sname##_##identifier##_next(&iter); \\\n" +" ++i; \\\n" +" } \\\n" +" sname##_##identifier##_end(&iter); \\\n" +" if (!found) \\\n" +" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n" +" return found; \\\n" +" } \n" +"#define COLLECTION_PROPERTY_LOOKUP_INT_TRUE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n" +" { return sname##_##identifier##_lookup_int(ptr, key, r_ptr); } \n" +"\n" +"#define COLLECTION_PROPERTY_LOOKUP_STRING_FALSE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n" +" { \\\n" +" memset(r_ptr, 0, sizeof(*r_ptr)); \\\n" +" return 0; \\\n" +" } \n" +"#define COLLECTION_PROPERTY_LOOKUP_STRING_TRUE(sname, identifier) \\\n" +" inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n" +" { return sname##_##identifier##_lookup_string(ptr, key, r_ptr); } \n" +"\n" +"#define COLLECTION_PROPERTY(collection_funcs, type, sname, identifier, has_length, has_lookup_int, has_lookup_string) \\\n" " typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n" " sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n" +" COLLECTION_PROPERTY_LENGTH_##has_length(sname, identifier) \\\n" +" COLLECTION_PROPERTY_LOOKUP_INT_##has_lookup_int(sname, identifier) \\\n" +" COLLECTION_PROPERTY_LOOKUP_STRING_##has_lookup_string(sname, identifier) \\\n" " Collection<sname, type, sname##_##identifier##_begin, \\\n" -" sname##_##identifier##_next, sname##_##identifier##_end> identifier;\n" +" sname##_##identifier##_next, sname##_##identifier##_end, \\\n" +" sname##_##identifier##_length_wrap, \\\n" +" sname##_##identifier##_lookup_int_wrap, sname##_##identifier##_lookup_string_wrap, collection_funcs> identifier;\n" "\n" "class Pointer {\n" "public:\n" @@ -2923,7 +3448,7 @@ static const char *cpp_classes = "" "public:\n" " T data[Tsize];\n" "\n" -" Array() {}\n" +" Array() {}\n" " Array(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); }\n" " const Array<T, Tsize>& operator=(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); " "return *this; }\n" @@ -2931,9 +3456,36 @@ static const char *cpp_classes = "" " operator T*() { return data; }\n" "};\n" "\n" +"template<typename T>\n" +"class DynamicArray {\n" +"public:\n" +" T *data;\n" +" int length;\n" +"\n" +" DynamicArray() : data(NULL), length(0) {}\n" +" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float*)malloc(sizeof(T) * new_length); }\n" +" DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n" +" const DynamicArray<T>& operator=(const DynamicArray<T>& other) { copy_from(other); return *this; }\n" +"\n" +" ~DynamicArray() { if (data) free(data); }\n" +"\n" +" operator T*() { return data; }\n" +"\n" +"protected:\n" +" void copy_from(const DynamicArray<T>& other) {\n" +" if (data) free(data);\n" +" data = (float*)malloc(sizeof(T) * other.length);\n" +" memcpy(data, other.data, sizeof(T) * other.length);\n" +" length = other.length;\n" +" }\n" +"};\n" +"\n" "typedef void (*TBeginFunc)(CollectionPropertyIterator *iter, PointerRNA *ptr);\n" "typedef void (*TNextFunc)(CollectionPropertyIterator *iter);\n" "typedef void (*TEndFunc)(CollectionPropertyIterator *iter);\n" +"typedef int (*TLengthFunc)(PointerRNA *ptr);\n" +"typedef int (*TLookupIntFunc)(PointerRNA *ptr, int key, PointerRNA *r_ptr);\n" +"typedef int (*TLookupStringFunc)(PointerRNA *ptr, const char *key, PointerRNA *r_ptr);\n" "\n" "template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n" "class CollectionIterator {\n" @@ -2964,26 +3516,97 @@ static const char *cpp_classes = "" " bool init;\n" "};\n" "\n" -"template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n" -"class Collection {\n" +"template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend,\n" +" TLengthFunc Tlength, TLookupIntFunc Tlookup_int, TLookupStringFunc Tlookup_string,\n" +" typename Tcollection_funcs>\n" +"class Collection : public Tcollection_funcs {\n" "public:\n" -" Collection(const PointerRNA &p) : ptr(p) {}\n" +" Collection(const PointerRNA &p) : Tcollection_funcs(p), ptr(p) {}\n" "\n" " void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n" " { iter.begin(ptr); }\n" " CollectionIterator<T, Tbegin, Tnext, Tend> end()\n" " { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n" +"" +" int length()\n" +" { return Tlength(&ptr); }\n" +" T operator[](int key)\n" +" { PointerRNA r_ptr; Tlookup_int(&ptr, key, &r_ptr); return T(r_ptr); }\n" +" T operator[](const std::string &key)\n" +" { PointerRNA r_ptr; Tlookup_string(&ptr, key.c_str(), &r_ptr); return T(r_ptr); }\n" "\n" "private:\n" " PointerRNA ptr;\n" "};\n" +"\n" +"class DefaultCollectionFunctions {\n" +"public:\n" +" DefaultCollectionFunctions(const PointerRNA &p) {}\n" +"};\n" +"\n" "\n"; +static int rna_is_collection_prop(PropertyRNA *prop) +{ + if (!(prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))) + if (prop->type == PROP_COLLECTION) + return 1; + + return 0; +} + +static int rna_is_collection_functions_struct(const char **collection_structs, const char *struct_name) +{ + int a = 0, found = 0; + + while (collection_structs[a]) { + if (!strcmp(collection_structs[a], struct_name)) { + found = 1; + break; + } + a++; + } + + return found; +} + +static void rna_generate_header_class_cpp(StructDefRNA *ds, FILE *f) +{ + StructRNA *srna = ds->srna; + PropertyDefRNA *dp; + FunctionDefRNA *dfunc; + + fprintf(f, "/**************** %s ****************/\n\n", srna->name); + + fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); + fprintf(f, "public:\n"); + fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier, + (srna->base) ? srna->base->identifier : "Pointer"); + for (dp = ds->cont.properties.first; dp; dp = dp->next) + if (rna_is_collection_prop(dp->prop)) + fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier); + fprintf(f, "\n\t\t{}\n\n"); + + for (dp = ds->cont.properties.first; dp; dp = dp->next) + rna_def_property_funcs_header_cpp(f, ds->srna, dp); + + fprintf(f, "\n"); + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) + rna_def_struct_function_header_cpp(f, srna, dfunc); + + fprintf(f, "};\n\n"); +} + static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f) { StructDefRNA *ds; PropertyDefRNA *dp; StructRNA *srna; + FunctionDefRNA *dfunc; + const char *first_collection_func_struct = NULL; + const char *collection_func_structs[256] = {NULL}; + int all_collection_func_structs = 0; + int max_collection_func_structs = sizeof(collection_func_structs) / sizeof(collection_func_structs[0]) - 1; fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n"); fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n"); @@ -3000,38 +3623,86 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f) fprintf(f, "/**************** Declarations ****************/\n\n"); - for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) + for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { fprintf(f, "class %s;\n", ds->srna->identifier); + } fprintf(f, "\n"); + /* first get list of all structures used as collection functions, so they'll be declared first */ + for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { + for (dp = ds->cont.properties.first; dp; dp = dp->next) { + if (rna_is_collection_prop(dp->prop)) { + PropertyRNA *prop = dp->prop; + + if (prop->srna) { + /* store name of structure which first uses custom functions for collections */ + if (first_collection_func_struct == NULL) + first_collection_func_struct = ds->srna->identifier; + + if (!rna_is_collection_functions_struct(collection_func_structs, (char*)prop->srna)) { + if (all_collection_func_structs >= max_collection_func_structs) { + printf("Array size to store all collection structures names is too small\n"); + exit(1); + } + + collection_func_structs[all_collection_func_structs++] = (char*)prop->srna; + } + } + } + } + } + + /* declare all structures in such order: + * - first N structures which doesn't use custom functions for collections + * - all structures used for custom functions in collections + * - all the rest structures + * such an order prevents usage of non-declared classes + */ for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { srna = ds->srna; - fprintf(f, "/**************** %s ****************/\n\n", srna->name); + if (!strcmp(srna->identifier, first_collection_func_struct)) { + StructDefRNA *ds2; + StructRNA *srna2; - fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); - fprintf(f, "public:\n"); - fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier, - (srna->base) ? srna->base->identifier : "Pointer"); - for (dp = ds->cont.properties.first; dp; dp = dp->next) - if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))) - if (dp->prop->type == PROP_COLLECTION) - fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier); - fprintf(f, "\n\t\t{}\n\n"); + for (ds2 = DefRNA.structs.first; ds2; ds2 = ds2->cont.next) { + srna2 = ds2->srna; - for (dp = ds->cont.properties.first; dp; dp = dp->next) - rna_def_property_funcs_header_cpp(f, ds->srna, dp); - fprintf(f, "};\n\n"); + if (rna_is_collection_functions_struct(collection_func_structs, srna2->identifier)) { + rna_generate_header_class_cpp(ds2, f); + } + } + } + + if (!rna_is_collection_functions_struct(collection_func_structs, srna->identifier)) + rna_generate_header_class_cpp(ds, f); } + fprintf(f, "} /* namespace BL */\n"); + fprintf(f, "\n"); fprintf(f, "/**************** Implementation ****************/\n"); + fprintf(f, "\n"); + + fprintf(f, "/* Structure prototypes */\n\n"); + fprintf(f, "extern \"C\" {\n"); + rna_generate_struct_prototypes(f); + fprintf(f, "}\n\n"); + + fprintf(f, "namespace BL {\n"); for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { + srna = ds->srna; + for (dp = ds->cont.properties.first; dp; dp = dp->next) rna_def_property_funcs_impl_cpp(f, ds->srna, dp); fprintf(f, "\n"); + + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) + rna_def_struct_function_impl_cpp(f, srna, dfunc); + + fprintf(f, "\n"); } fprintf(f, "}\n\n#endif /* __RNA_BLENDER_CPP_H__ */\n\n"); @@ -3068,34 +3739,8 @@ static int rna_preprocess(const char *outfile) rna_auto_types(); - - /* create RNA_blender_cpp.h */ - strcpy(deffile, outfile); - strcat(deffile, "RNA_blender_cpp.h" TMP_EXT); - status = (DefRNA.error != 0); - if (status) { - make_bad_file(deffile, __LINE__); - } - else { - file = fopen(deffile, "w"); - - if (!file) { - fprintf(stderr, "Unable to open file: %s\n", deffile); - status = 1; - } - else { - rna_generate_header_cpp(brna, file); - fclose(file); - status = (DefRNA.error != 0); - } - } - - replace_if_different(deffile, NULL); - - rna_sort(brna); - /* create rna_gen_*.c files */ for (i = 0; PROCESS_ITEMS[i].filename; i++) { strcpy(deffile, outfile); @@ -3128,6 +3773,31 @@ static int rna_preprocess(const char *outfile) replace_if_different(deffile, deps); } + /* create RNA_blender_cpp.h */ + strcpy(deffile, outfile); + strcat(deffile, "RNA_blender_cpp.h" TMP_EXT); + + if (status) { + make_bad_file(deffile, __LINE__); + } + else { + file = fopen(deffile, "w"); + + if (!file) { + fprintf(stderr, "Unable to open file: %s\n", deffile); + status = 1; + } + else { + rna_generate_header_cpp(brna, file); + fclose(file); + status = (DefRNA.error != 0); + } + } + + replace_if_different(deffile, NULL); + + rna_sort(brna); + /* create RNA_blender.h */ strcpy(deffile, outfile); strcat(deffile, "RNA_blender.h" TMP_EXT); |