diff options
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_define.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 47 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 9 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal_types.h | 5 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 101 |
7 files changed, 129 insertions, 47 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 39232113581..e631e037e74 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -854,7 +854,6 @@ char *RNA_pointer_as_string(PointerRNA *ptr); /* Function */ const char *RNA_function_identifier(FunctionRNA *func); -PropertyRNA *RNA_function_return(FunctionRNA *func); const char *RNA_function_ui_description(FunctionRNA *func); int RNA_function_flag(FunctionRNA *func); int RNA_function_defined(FunctionRNA *func); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 37abe44f128..f340834d93b 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -172,6 +172,7 @@ void RNA_def_property_srna(PropertyRNA *prop, const char *type); FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call); FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call); void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret); +void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret); void RNA_def_function_flag(FunctionRNA *func, int flag); void RNA_def_function_ui_description(FunctionRNA *func, const char *description); diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 5bdfe228e89..ca14acb4060 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1236,16 +1236,18 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA for(; dparm; dparm= dparm->next) { if(dparm->prop->arraydimension) ptrstr= "*"; - else if(dparm->prop==func->ret) + else if(dparm->prop==func->c_ret) ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "*": ""; + else if ((dparm->prop->flag & PROP_RETURN)) + ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "**": "*"; else ptrstr= (dparm->prop->type == PROP_POINTER)? "*": ""; - + fprintf(f, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); } fprintf(f, "\tchar *_data"); - if(func->ret) fprintf(f, ", *_retdata"); + if(func->c_ret) fprintf(f, ", *_retdata"); fprintf(f, ";\n"); fprintf(f, "\t\n"); @@ -1259,7 +1261,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= dfunc->cont.properties.first; for(; dparm; dparm= dparm->next) { - if(dparm->prop==func->ret) + if ((dparm->prop->flag & PROP_RETURN)) + ptrstr= ""; + else + ptrstr= "*"; + + if(dparm->prop==func->c_ret) fprintf(f, "\t_retdata= _data;\n"); else if(dparm->prop->arraydimension) fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); @@ -1267,10 +1274,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if(dparm->prop->flag & PROP_RNAPTR) fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); else - fprintf(f, "\t%s= *((%s%s**)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); + fprintf(f, "\t%s= %s((%s%s**)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); } else - fprintf(f, "\t%s= *((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); + fprintf(f, "\t%s= %s((%s%s*)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); if(dparm->next) fprintf(f, "\t_data+= %d;\n", rna_parameter_size(dparm->prop)); @@ -1279,7 +1286,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA if(dfunc->call) { fprintf(f, "\t\n"); fprintf(f, "\t"); - if(func->ret) fprintf(f, "%s= ", func->ret->identifier); + if(func->c_ret) fprintf(f, "%s= ", func->c_ret->identifier); fprintf(f, "%s(", dfunc->call); first= 1; @@ -1303,7 +1310,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= dfunc->cont.properties.first; for(; dparm; dparm= dparm->next) { - if(dparm->prop==func->ret) + if(dparm->prop==func->c_ret) continue; if(!first) fprintf(f, ", "); @@ -1314,10 +1321,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA fprintf(f, ");\n"); - if(func->ret) { - dparm= rna_find_parameter_def(func->ret); + if(func->c_ret) { + dparm= rna_find_parameter_def(func->c_ret); ptrstr= (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) || (dparm->prop->arraydimension))? "*": ""; - fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->ret->identifier); + fprintf(f, "\t*((%s%s%s*)_retdata)= %s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier); } } @@ -1552,13 +1559,14 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA PropertyDefRNA *dparm; StructDefRNA *dsrna; int first; + char *ptrstr; dsrna= rna_find_struct_def(srna); func= dfunc->func; /* return type */ for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { - if(dparm->prop==func->ret) { + if(dparm->prop==func->c_ret) { if(dparm->prop->arraydimension) fprintf(f, "XXX no array return types yet"); /* XXX not supported */ else if(dparm->prop->type == PROP_POINTER && !(dparm->prop->flag & PROP_RNAPTR)) @@ -1600,18 +1608,23 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA /* defined parameters */ for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { - if(dparm->prop==func->ret) + if(dparm->prop==func->c_ret) continue; if(!first) fprintf(f, ", "); first= 0; + if((dparm->prop->flag & PROP_RETURN)) + ptrstr= "*"; + else + ptrstr= ""; + if(dparm->prop->arraydimension) fprintf(f, "%s%s %s[%d]", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier, dparm->prop->totarraylength); else if(dparm->prop->type == PROP_POINTER) - fprintf(f, "%s%s *%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier); + fprintf(f, "%s%s *%s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), (dparm->prop->flag & PROP_RNAPTR) ? "" : ptrstr, dparm->prop->identifier); else - fprintf(f, "%s%s %s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), dparm->prop->identifier); + fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); } fprintf(f, ");\n"); @@ -1890,8 +1903,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f) dfunc= rna_find_function_def(func); if(dfunc->gencall) fprintf(f, "\t%s,\n", dfunc->gencall); else fprintf(f, "\tNULL,\n"); - - if(func->ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->ret->identifier); + + if(func->c_ret) fprintf(f, "\t(PropertyRNA*)&rna_%s_%s_%s\n", srna->identifier, func->identifier, func->c_ret->identifier); else fprintf(f, "\tNULL\n"); fprintf(f, "};\n"); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 7dcc72e4158..d8b31f4093e 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3464,11 +3464,6 @@ const char *RNA_function_identifier(FunctionRNA *func) return func->identifier; } -PropertyRNA *RNA_function_return(FunctionRNA *func) -{ - return func->ret; -} - const char *RNA_function_ui_description(FunctionRNA *func) { return func->description; @@ -3929,7 +3924,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt tid= RNA_struct_identifier(ptr->type); fid= RNA_function_identifier(func); - pret= RNA_function_return(func); + pret= func->c_ret; flen= strlen(format); RNA_parameter_list_create(&parms, ptr, func); @@ -3937,14 +3932,17 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt for(i= 0, ofs= 0; iter.valid; RNA_parameter_list_next(&iter), i++) { parm= iter.parm; + flag= RNA_property_flag(parm); if(parm==pret) { retdata= iter.data; continue; } + else if (flag & PROP_RETURN) { + continue; + } pid= RNA_property_identifier(parm); - flag= RNA_property_flag(parm); if (ofs>=flen || format[ofs]=='N') { if (flag & PROP_REQUIRED) { diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 9bf5afdac48..854776e8742 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2417,9 +2417,16 @@ FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, C return func; } +/* C return value only!, multiple rna returns can be done with RNA_def_function_return_mark */ void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret) { - func->ret= ret; + func->c_ret= ret; + + RNA_def_function_return_mark(func, ret); +} + +void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret) +{ ret->flag|=PROP_RETURN; } diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index 4f05e6132f7..bef568bfa7d 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -118,8 +118,9 @@ struct FunctionRNA { /* callback to execute the function */ CallFunc call; - /* parameter for the return value */ - PropertyRNA *ret; + /* parameter for the return value + * note: this is only the C return value, rna functions can have multiple return values */ + PropertyRNA *c_ret; }; struct PropertyRNA { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c8f0a29ca64..fd28fa04c06 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -2564,11 +2564,13 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) PointerRNA funcptr; ParameterList parms; ParameterIterator iter; - PropertyRNA *pret, *parm; + PropertyRNA *parm; PyObject *ret, *item; - int i, args_len, parms_len, flag, err= 0, kw_tot= 0, kw_arg; + int i, args_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg; const char *parm_id; - void *retdata= NULL; + + PropertyRNA *pret_single= NULL; + void *retdata_single= NULL; /* Should never happen but it does in rare cases */ if(self_ptr==NULL) { @@ -2586,12 +2588,12 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) * the same ID as the functions. */ RNA_pointer_create(self_ptr->id.data, &RNA_Function, self_func, &funcptr); - pret= RNA_function_return(self_func); args_len= PyTuple_GET_SIZE(args); RNA_parameter_list_create(&parms, self_ptr, self_func); RNA_parameter_list_begin(&parms, &iter); - parms_len = RNA_parameter_list_size(&parms); + parms_len= RNA_parameter_list_size(&parms); + ret_len= 0; if(args_len + (kw ? PyDict_Size(kw):0) > parms_len) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, args_len); @@ -2601,14 +2603,20 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) /* parse function parameters */ for (i= 0; iter.valid && err==0; RNA_parameter_list_next(&iter)) { parm= iter.parm; + flag= RNA_property_flag(parm); + + /* only useful for single argument returns, we'll need another list loop for multiple */ + if (flag & PROP_RETURN) { + ret_len++; + if (pret_single==NULL) { + pret_single= parm; + retdata_single= iter.data; + } - if (parm==pret) { - retdata= iter.data; continue; } parm_id= RNA_property_identifier(parm); - flag= RNA_property_flag(parm); item= NULL; if ((i < args_len) && (flag & PROP_REQUIRED)) { @@ -2740,8 +2748,25 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) /* return value */ if(err==0) { - if(pret) { - ret= pyrna_param_to_py(&funcptr, pret, retdata); + if (ret_len > 0) { + if (ret_len > 1) { + ret= PyTuple_New(ret_len); + i= 0; /* arg index */ + + RNA_parameter_list_begin(&parms, &iter); + + for(; iter.valid; RNA_parameter_list_next(&iter)) { + parm= iter.parm; + flag= RNA_property_flag(parm); + + if (flag & PROP_RETURN) + PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); + } + + RNA_parameter_list_end(&iter); + } + else + ret= pyrna_param_to_py(&funcptr, pret_single, retdata_single); /* possible there is an error in conversion */ if(ret==NULL) @@ -3980,15 +4005,18 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun extern void BPY_update_modules( void ); //XXX temp solution +/* TODO - multiple return values like with rna functions */ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) { PyObject *args; PyObject *ret= NULL, *py_class, *py_class_instance, *item, *parmitem; - PropertyRNA *pret= NULL, *parm; + PropertyRNA *parm; ParameterIterator iter; PointerRNA funcptr; - void *retdata= NULL; - int err= 0, i, flag; + int err= 0, i, flag, ret_len=0; + + PropertyRNA *pret_single= NULL; + void *retdata_single= NULL; PyGILState_STATE gilstate; @@ -4014,10 +4042,9 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par if (py_class_instance) { /* Initializing the class worked, now run its invoke function */ item= PyObject_GetAttrString(py_class, RNA_function_identifier(func)); - flag= RNA_function_flag(func); +// flag= RNA_function_flag(func); if(item) { - pret= RNA_function_return(func); RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ @@ -4028,9 +4055,16 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par /* parse function parameters */ for (i= 1; iter.valid; RNA_parameter_list_next(&iter)) { parm= iter.parm; + flag= RNA_property_flag(parm); + + /* only useful for single argument returns, we'll need another list loop for multiple */ + if (flag & PROP_RETURN) { + ret_len++; + if (pret_single==NULL) { + pret_single= parm; + retdata_single= iter.data; + } - if (parm==pret) { - retdata= iter.data; continue; } @@ -4060,8 +4094,37 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par err= -1; } else { - if(retdata) - err= pyrna_py_to_prop(&funcptr, pret, retdata, ret, "calling class function:"); + if(ret_len==1) { + err= pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "calling class function:"); + } + else if (ret_len > 1) { + + if(PyTuple_Check(ret)==0) { + PyErr_Format(PyExc_RuntimeError, "expected class %.200s, function %.200s to return a tuple of size %d.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), ret_len); + err= -1; + } + else if (PyTuple_GET_SIZE(ret) != ret_len) { + PyErr_Format(PyExc_RuntimeError, "class %.200s, function %.200s to returned %d items, expected %d.", RNA_struct_identifier(ptr->type), RNA_function_identifier(func), PyTuple_GET_SIZE(ret), ret_len); + err= -1; + } + else { + + RNA_parameter_list_begin(parms, &iter); + + /* parse function parameters */ + for (i= 0; iter.valid; RNA_parameter_list_next(&iter)) { + parm= iter.parm; + flag= RNA_property_flag(parm); + + /* only useful for single argument returns, we'll need another list loop for multiple */ + if (flag & PROP_RETURN) { + err= pyrna_py_to_prop(&funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); + if(err) + break; + } + } + } + } Py_DECREF(ret); } |