RNA functions

Fixed and completed support for returning multiple values. This includes support for returning arrays, both fixed and dynamically sized. The way this is achieved is by storing an additional int value next to the dynamic parameter in the ParameterList stack which gets passed to the C function as an additional parameter. In the case of return parameters it is duty of the C function to set this int to the correct length value for the dynamic parameter (which makes sense). Note that for the dynamic output/return parameter it is assumed the function has allocated that memory (which gets freed automatically).

Also, I cleaned the makesrna's bridge function generation code a bit and renamed PROP_RETURN to PROP_OUTPUT, which represents better the reality now that there are multiple returns. The function now to mark multiple returns (outputs) is RNA_def_function_output.

For an example, look at Action.get_frame_range in rna_action_api.c, by the way Aligorith I removed the #ifdef for this function now that there's support for returning arrays, feel free to modify (the function seems to work).
This commit is contained in:
2010-01-24 10:51:59 +00:00
parent 7c21eb7cd5
commit 9733e902a5
14 changed files with 220 additions and 100 deletions

View File

@@ -886,6 +886,10 @@ void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value);
void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value); void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value);
void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value); void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value);
void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value); void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value);
int RNA_parameter_length_get(ParameterList *parms, PropertyRNA *parm);
int RNA_parameter_length_get_data(ParameterList *parms, PropertyRNA *parm, void *data);
void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int length);
void RNA_parameter_length_set_data(ParameterList *parms, PropertyRNA *parm, void *data, int length);
int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms); int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms);
int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms); int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms);

View File

@@ -172,7 +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(StructRNA *srna, const char *identifier, const char *call);
FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc 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(FunctionRNA *func, PropertyRNA *ret);
void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret); void RNA_def_function_output(FunctionRNA *func, PropertyRNA *ret);
void RNA_def_function_flag(FunctionRNA *func, int flag); void RNA_def_function_flag(FunctionRNA *func, int flag);
void RNA_def_function_ui_description(FunctionRNA *func, const char *description); void RNA_def_function_ui_description(FunctionRNA *func, const char *description);

View File

@@ -150,7 +150,7 @@ typedef enum PropertyFlag {
/* function paramater flags */ /* function paramater flags */
PROP_REQUIRED = 1<<2, PROP_REQUIRED = 1<<2,
PROP_RETURN = 1<<3, PROP_OUTPUT = 1<<3,
PROP_RNAPTR = 1<<11, PROP_RNAPTR = 1<<11,
/* registering */ /* registering */
PROP_REGISTER = 1<<4, PROP_REGISTER = 1<<4,

View File

@@ -1290,8 +1290,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
StructRNA *srna; StructRNA *srna;
FunctionRNA *func; FunctionRNA *func;
PropertyDefRNA *dparm; PropertyDefRNA *dparm;
char *funcname, *ptrstr; PropertyType type;
int first; char *funcname, *ptrstr, *valstr;
int flag, pout, cptr, first;
srna= dsrna->srna; srna= dsrna->srna;
func= dfunc->func; func= dfunc->func;
@@ -1316,19 +1317,30 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
dparm= dfunc->cont.properties.first; dparm= dfunc->cont.properties.first;
for(; dparm; dparm= dparm->next) { for(; dparm; dparm= dparm->next) {
if(dparm->prop->arraydimension) type = dparm->prop->type;
flag = dparm->prop->flag;
pout = (flag & PROP_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
if(dparm->prop==func->c_ret)
ptrstr= cptr || dparm->prop->arraydimension ? "*" : "";
/* XXX only arrays and strings are allowed to be dynamic, is this checked anywhere? */
else if (cptr || (flag & PROP_DYNAMIC))
ptrstr= pout ? "**" : "*";
/* 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= "*"; ptrstr= "*";
else if(dparm->prop==func->c_ret) /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, but type name for string props is already char*, so leave empty */
ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "*": ""; else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
else if ((dparm->prop->flag & PROP_RETURN)) { ptrstr= "";
if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING)) else
ptrstr= ""; ptrstr= pout ? "*" : "";
else
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, "\t%s%s %s%s;\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
/* for dynamic parameters we pass an additional int for the length of the parameter */
if (flag & PROP_DYNAMIC)
fprintf(f, "\tint %s%s_len;\n", pout ? "*" : "", dparm->prop->identifier);
} }
fprintf(f, "\tchar *_data"); fprintf(f, "\tchar *_data");
@@ -1349,30 +1361,45 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
dparm= dfunc->cont.properties.first; dparm= dfunc->cont.properties.first;
for(; dparm; dparm= dparm->next) { for(; dparm; dparm= dparm->next) {
if ((dparm->prop->flag & PROP_RETURN)) type = dparm->prop->type;
ptrstr= ""; flag = dparm->prop->flag;
else pout = (flag & PROP_OUTPUT);
ptrstr= "*"; cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
if(dparm->prop==func->c_ret) if(dparm->prop==func->c_ret)
fprintf(f, "\t_retdata= _data;\n"); fprintf(f, "\t_retdata= _data;\n");
else if(dparm->prop->arraydimension) else {
fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); if (cptr || (flag & PROP_DYNAMIC)) {
else if(dparm->prop->type == PROP_POINTER) { ptrstr= "**";
if(dparm->prop->flag & PROP_RNAPTR) valstr= "*";
fprintf(f, "\t%s= ((%s%s*)_data);\n", dparm->prop->identifier, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); }
else else if (type == PROP_POINTER || dparm->prop->arraydimension) {
fprintf(f, "\t%s= %s((%s%s**)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); ptrstr= "*";
} valstr= "";
else { }
if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING)) else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) {
fprintf(f, "\t%s= %s((%s%s)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); ptrstr= "";
else valstr= "";
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 {
ptrstr= "*";
valstr= "*";
}
fprintf(f, "\t%s= ", dparm->prop->identifier);
if (!pout)
fprintf(f, "%s", valstr);
fprintf(f, "((%s%s%s)_data);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr);
/* this must be kept in sync with RNA_parameter_length_get_data, we could just call the function directly, but this is faster */
if (flag & PROP_DYNAMIC)
fprintf(f, "\t%s_len= %s((int *)(_data+%d));\n", dparm->prop->identifier, pout ? "" : "*", rna_parameter_size(dparm->prop));
} }
if(dparm->next) if(dparm->next)
fprintf(f, "\t_data+= %d;\n", rna_parameter_size(dparm->prop)); fprintf(f, "\t_data+= %d;\n", rna_parameter_size_alloc(dparm->prop));
} }
if(dfunc->call) { if(dfunc->call) {
@@ -1412,6 +1439,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
first= 0; first= 0;
fprintf(f, "%s", dparm->prop->identifier); fprintf(f, "%s", dparm->prop->identifier);
if (dparm->prop->flag & PROP_DYNAMIC)
fprintf(f, ", %s_len", dparm->prop->identifier);
} }
fprintf(f, ");\n"); fprintf(f, ");\n");
@@ -1653,7 +1683,8 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
FunctionRNA *func; FunctionRNA *func;
PropertyDefRNA *dparm; PropertyDefRNA *dparm;
StructDefRNA *dsrna; StructDefRNA *dsrna;
int first; PropertyType type;
int flag, pout, cptr, first;
char *ptrstr; char *ptrstr;
dsrna= rna_find_struct_def(srna); dsrna= rna_find_struct_def(srna);
@@ -1706,25 +1737,33 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA
/* defined parameters */ /* defined parameters */
for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) { for(dparm= dfunc->cont.properties.first; dparm; dparm= dparm->next) {
type = dparm->prop->type;
flag = dparm->prop->flag;
pout = (flag & PROP_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
if(dparm->prop==func->c_ret) if(dparm->prop==func->c_ret)
continue; continue;
if (cptr || (flag & PROP_DYNAMIC))
ptrstr= pout ? "**" : "*";
else if (type == PROP_POINTER || dparm->prop->arraydimension)
ptrstr= "*";
else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
ptrstr= "";
else
ptrstr= pout ? "*" : "";
if(!first) fprintf(f, ", "); if(!first) fprintf(f, ", ");
first= 0; first= 0;
if((dparm->prop->type == PROP_STRING && dparm->prop->flag & PROP_THICK_WRAP)) if(!(flag & PROP_DYNAMIC) && dparm->prop->arraydimension)
ptrstr= "";
else 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); 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%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), (dparm->prop->flag & PROP_RNAPTR) ? "" : ptrstr, dparm->prop->identifier);
else else
fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier); fprintf(f, "%s%s %s%s", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop), ptrstr, dparm->prop->identifier);
if (flag & PROP_DYNAMIC)
fprintf(f, ", int %s%s_len", pout ? "*" : "", dparm->prop->identifier);
} }
fprintf(f, ");\n"); fprintf(f, ");\n");

View File

@@ -3603,7 +3603,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr,
/* allocate data */ /* allocate data */
for(parm= func->cont.properties.first; parm; parm= parm->next) for(parm= func->cont.properties.first; parm; parm= parm->next)
tot+= rna_parameter_size(parm); tot+= rna_parameter_size_alloc(parm);
parms->data= MEM_callocN(tot, "RNA_parameter_list_create"); parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
parms->func= func; parms->func= func;
@@ -3644,7 +3644,11 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr,
} }
} }
data= ((char*)data) + size; /* set length to 0 */
if (parm->flag & PROP_DYNAMIC)
*((int *)(((char *)data) + size))= 0;
data= ((char*)data) + rna_parameter_size_alloc(parm);
} }
return parms; return parms;
@@ -3666,7 +3670,7 @@ void RNA_parameter_list_free(ParameterList *parms)
MEM_freeN(array); MEM_freeN(array);
} }
tot+= rna_parameter_size(parm); tot+= rna_parameter_size_alloc(parm);
} }
MEM_freeN(parms->data); MEM_freeN(parms->data);
@@ -3692,7 +3696,7 @@ void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
iter->offset= 0; iter->offset= 0;
if(iter->valid) { if(iter->valid) {
iter->size= rna_parameter_size(iter->parm); iter->size= rna_parameter_size_alloc(iter->parm);
iter->data= (((char*)iter->parms->data)+iter->offset); iter->data= (((char*)iter->parms->data)+iter->offset);
ptype= RNA_property_type(iter->parm); ptype= RNA_property_type(iter->parm);
} }
@@ -3707,7 +3711,7 @@ void RNA_parameter_list_next(ParameterIterator *iter)
iter->valid= iter->parm != NULL; iter->valid= iter->parm != NULL;
if(iter->valid) { if(iter->valid) {
iter->size= rna_parameter_size(iter->parm); iter->size= rna_parameter_size_alloc(iter->parm);
iter->data= (((char*)iter->parms->data)+iter->offset); iter->data= (((char*)iter->parms->data)+iter->offset);
ptype= RNA_property_type(iter->parm); ptype= RNA_property_type(iter->parm);
} }
@@ -3778,6 +3782,51 @@ void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void
RNA_parameter_set(parms, parm, value); RNA_parameter_set(parms, parm, value);
} }
int RNA_parameter_length_get(ParameterList *parms, PropertyRNA *parm)
{
ParameterIterator iter;
int len= 0;
RNA_parameter_list_begin(parms, &iter);
for(; iter.valid; RNA_parameter_list_next(&iter))
if(iter.parm==parm)
break;
if(iter.valid)
len= RNA_parameter_length_get_data(parms, parm, iter.data);
RNA_parameter_list_end(&iter);
return len;
}
void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int length)
{
ParameterIterator iter;
RNA_parameter_list_begin(parms, &iter);
for(; iter.valid; RNA_parameter_list_next(&iter))
if(iter.parm==parm)
break;
if(iter.valid)
RNA_parameter_length_set_data(parms, parm, iter.data, length);
RNA_parameter_list_end(&iter);
}
int RNA_parameter_length_get_data(ParameterList *parms, PropertyRNA *parm, void *data)
{
return *((int *)(((char *)data) + rna_parameter_size(parm)));
}
void RNA_parameter_length_set_data(ParameterList *parms, PropertyRNA *parm, void *data, int length)
{
*((int *)(((char *)data) + rna_parameter_size(parm)))= length;
}
int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms) int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
{ {
if(func->call) { if(func->call) {
@@ -4022,7 +4071,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
retdata= iter.data; retdata= iter.data;
continue; continue;
} }
else if (flag & PROP_RETURN) { else if (flag & PROP_OUTPUT) {
continue; continue;
} }

View File

@@ -41,40 +41,35 @@
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_curve_types.h" #include "DNA_curve_types.h"
/* XXX disabled until RNA allows returning arrays */
#if 0
/* return frame range of all curves (min, max) or (0, 1) if there are no keys */ /* return frame range of all curves (min, max) or (0, 1) if there are no keys */
int *rna_Action_get_frame_range(bAction *act, int *ret_length) void rna_Action_get_frame_range(bAction *act, int **frame_range, int *length_r)
{ {
int *ret; int *ret;
float start, end; float start, end;
calc_action_range(act, &start, &end, 1); calc_action_range(act, &start, &end, 1);
*ret_length= 2; *length_r= 2;
ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range"); ret= MEM_callocN(*length_r * sizeof(int), "rna_Action_get_frame_range");
ret[0]= (int)start; ret[0]= (int)start;
ret[1]= (int)end; ret[1]= (int)end;
return ret; *frame_range= ret;
} }
#endif
#else #else
void RNA_api_action(StructRNA *srna) void RNA_api_action(StructRNA *srna)
{ {
#if 0
FunctionRNA *func; FunctionRNA *func;
PropertyRNA *parm; PropertyRNA *parm;
func= RNA_def_function(srna, "get_frame_range", "rna_Action_get_frame_range"); func= RNA_def_function(srna, "get_frame_range", "rna_Action_get_frame_range");
RNA_def_function_ui_description(func, "Get action frame range as a (min, max) tuple."); RNA_def_function_ui_description(func, "Get action frame range as a (min, max) tuple.");
parm= RNA_def_int_array(func, "frame_range", 1, NULL, 0, 0, "", "Action frame range.", 0, 0); parm= RNA_def_int_array(func, "frame_range", 1, NULL, 0, 0, "", "Action frame range.", 0, 0);
RNA_def_property_flag(parm, PROP_DYNAMIC_ARRAY); RNA_def_property_flag(parm, PROP_DYNAMIC);
RNA_def_function_return(func, parm); RNA_def_function_output(func, parm);
#endif
} }
#endif #endif

View File

@@ -2419,17 +2419,26 @@ FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, C
return func; return func;
} }
/* C return value only!, multiple rna returns can be done with RNA_def_function_return_mark */ /* C return value only!, multiple RNA returns can be done with RNA_def_function_output */
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret) void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
{ {
if (ret->flag & PROP_DYNAMIC) {
fprintf(stderr, "RNA_def_function_return: %s.%s, dynamic values are not allowed as strict returns, use RNA_def_function_output instead.\n", func->identifier, ret->identifier);
return;
}
else if (ret->arraydimension) {
fprintf(stderr, "RNA_def_function_return: %s.%s, arrays are not allowed as strict returns, use RNA_def_function_output instead.\n", func->identifier, ret->identifier);
return;
}
func->c_ret= ret; func->c_ret= ret;
RNA_def_function_return_mark(func, ret); RNA_def_function_output(func, ret);
} }
void RNA_def_function_return_mark(FunctionRNA *func, PropertyRNA *ret) void RNA_def_function_output(FunctionRNA *func, PropertyRNA *ret)
{ {
ret->flag|=PROP_RETURN; ret->flag|= PROP_OUTPUT;
} }
void RNA_def_function_flag(FunctionRNA *func, int flag) void RNA_def_function_flag(FunctionRNA *func, int flag)
@@ -2448,6 +2457,7 @@ int rna_parameter_size(PropertyRNA *parm)
int len= parm->totarraylength; /* only supports fixed length at the moment */ int len= parm->totarraylength; /* only supports fixed length at the moment */
if(len > 0) { if(len > 0) {
/* XXX in other parts is mentioned that strings can be dynamic as well */
if (parm->flag & PROP_DYNAMIC) if (parm->flag & PROP_DYNAMIC)
return sizeof(void *); return sizeof(void *);
@@ -2497,6 +2507,18 @@ int rna_parameter_size(PropertyRNA *parm)
return sizeof(void *); return sizeof(void *);
} }
/* this function returns the size of the memory allocated for the parameter,
useful for instance for memory alignment or for storing additional information */
int rna_parameter_size_alloc(PropertyRNA *parm)
{
int size = rna_parameter_size(parm);
if (parm->flag & PROP_DYNAMIC)
size+= sizeof(int);
return size;
}
/* Dynamic Enums */ /* Dynamic Enums */
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item) void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item)

View File

@@ -331,6 +331,7 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *
/* Functions */ /* Functions */
int rna_parameter_size(struct PropertyRNA *parm); int rna_parameter_size(struct PropertyRNA *parm);
int rna_parameter_size_alloc(struct PropertyRNA *parm);
#endif /* RNA_INTERNAL_H */ #endif /* RNA_INTERNAL_H */

View File

@@ -497,13 +497,13 @@ void RNA_api_object(StructRNA *srna)
/* return location and normal */ /* return location and normal */
parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The hit location of this ray cast", -1e4, 1e4); parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The hit location of this ray cast", -1e4, 1e4);
RNA_def_property_flag(parm, PROP_THICK_WRAP); RNA_def_property_flag(parm, PROP_THICK_WRAP);
RNA_def_function_return_mark(func, parm); RNA_def_function_output(func, parm);
parm= RNA_def_float_vector(func, "normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "The face normal at the ray cast hit location", -1e4, 1e4); parm= RNA_def_float_vector(func, "normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "The face normal at the ray cast hit location", -1e4, 1e4);
RNA_def_property_flag(parm, PROP_THICK_WRAP); RNA_def_property_flag(parm, PROP_THICK_WRAP);
RNA_def_function_return_mark(func, parm); RNA_def_function_output(func, parm);
parm= RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no intersection is found.", 0, 0); parm= RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no intersection is found.", 0, 0);
RNA_def_function_return_mark(func, parm); RNA_def_function_output(func, parm);
/* DAG */ /* DAG */

View File

@@ -439,7 +439,7 @@ static int rna_Property_readonly_get(PointerRNA *ptr)
static int rna_Property_use_return_get(PointerRNA *ptr) static int rna_Property_use_return_get(PointerRNA *ptr)
{ {
PropertyRNA *prop= (PropertyRNA*)ptr->data; PropertyRNA *prop= (PropertyRNA*)ptr->data;
return prop->flag & PROP_RETURN ? 1:0; return prop->flag & PROP_OUTPUT ? 1:0;
} }
static int rna_Property_is_required_get(PointerRNA *ptr) static int rna_Property_is_required_get(PointerRNA *ptr)

View File

@@ -134,7 +134,7 @@ void RNA_api_scene_render(StructRNA *srna)
parm= RNA_def_int(func, "frame", INT_MIN, INT_MIN, INT_MAX, "", "Frame number to use, if unset the current frame will be used.", MINAFRAME, MAXFRAME); parm= RNA_def_int(func, "frame", INT_MIN, INT_MIN, INT_MAX, "", "Frame number to use, if unset the current frame will be used.", MINAFRAME, MAXFRAME);
parm= RNA_def_string(func, "name", "", FILE_MAX, "File Name", "the resulting filename from the scenes render settings."); parm= RNA_def_string(func, "name", "", FILE_MAX, "File Name", "the resulting filename from the scenes render settings.");
RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */ RNA_def_property_flag(parm, PROP_THICK_WRAP); /* needed for string return value */
RNA_def_function_return_mark(func, parm); RNA_def_function_output(func, parm);
} }
#endif #endif

View File

@@ -242,7 +242,7 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int
return data; return data;
} }
static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix) static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix)
{ {
int totdim, dim_size[MAX_ARRAY_DIMENSION]; int totdim, dim_size[MAX_ARRAY_DIMENSION];
int totitem; int totitem;
@@ -266,6 +266,8 @@ static int py_to_array(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, char *p
if (RNA_property_flag(prop) & PROP_DYNAMIC) { if (RNA_property_flag(prop) & PROP_DYNAMIC) {
/* not freeing allocated mem, RNA_parameter_list_free will do this */ /* not freeing allocated mem, RNA_parameter_list_free will do this */
*(char**)param_data= data; *(char**)param_data= data;
RNA_parameter_length_set_data(parms, prop, param_data, totitem);
} }
} }
else { else {
@@ -358,18 +360,18 @@ static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *
RNA_property_boolean_set_index(ptr, prop, index, *(int*)value); RNA_property_boolean_set_index(ptr, prop, index, *(int*)value);
} }
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix) int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, char *param_data, PyObject *py, const char *error_prefix)
{ {
int ret; int ret;
switch (RNA_property_type(prop)) { switch (RNA_property_type(prop)) {
case PROP_FLOAT: case PROP_FLOAT:
ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix); ret= py_to_array(py, ptr, prop, parms, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix);
break; break;
case PROP_INT: case PROP_INT:
ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix); ret= py_to_array(py, ptr, prop, parms, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix);
break; break;
case PROP_BOOLEAN: case PROP_BOOLEAN:
ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix); ret= py_to_array(py, ptr, prop, parms, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix);
break; break;
default: default:
PyErr_SetString(PyExc_TypeError, "not an array type"); PyErr_SetString(PyExc_TypeError, "not an array type");

View File

@@ -593,7 +593,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
break; break;
} }
} else { } else {
if (pyrna_py_to_prop(ptr, prop, NULL, item, error_prefix)) { if (pyrna_py_to_prop(ptr, prop, NULL, NULL, item, error_prefix)) {
error_val= -1; error_val= -1;
break; break;
} }
@@ -647,7 +647,7 @@ static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func)
int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix)
{ {
/* XXX hard limits should be checked here */ /* XXX hard limits should be checked here */
int type = RNA_property_type(prop); int type = RNA_property_type(prop);
@@ -670,7 +670,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
return -1; return -1;
} }
/* done getting the length */ /* done getting the length */
ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix); ok= pyrna_py_to_array(ptr, prop, parms, data, value, error_prefix);
if (!ok) { if (!ok) {
/* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */ /* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
@@ -688,7 +688,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
/* prefer not to have an exception here /* prefer not to have an exception here
* however so many poll functions return None or a valid Object. * however so many poll functions return None or a valid Object.
* its a hassle to convert these into a bool before returning, */ * its a hassle to convert these into a bool before returning, */
if(RNA_property_flag(prop) & PROP_RETURN) if(RNA_property_flag(prop) & PROP_OUTPUT)
param = PyObject_IsTrue( value ); param = PyObject_IsTrue( value );
else else
param = PyLong_AsSsize_t( value ); param = PyLong_AsSsize_t( value );
@@ -1990,7 +1990,7 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
} }
/* pyrna_py_to_prop sets its own exceptions */ /* pyrna_py_to_prop sets its own exceptions */
return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "StructRNA - item.attr = val:"); return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "StructRNA - item.attr = val:");
} }
static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self) static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
@@ -2066,7 +2066,7 @@ static int pyrna_prop_setattro( BPy_PropertyRNA *self, PyObject *pyname, PyObjec
if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) { if ((prop = RNA_struct_find_property(&r_ptr, name))) {
/* pyrna_py_to_prop sets its own exceptions */ /* pyrna_py_to_prop sets its own exceptions */
return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):"); return pyrna_py_to_prop(&r_ptr, prop, NULL, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
} }
} }
} }
@@ -2634,7 +2634,7 @@ static PyObject * pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *k
} }
} }
PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) PyObject *pyrna_param_to_py(PointerRNA *ptr, ParameterList *parms, PropertyRNA *prop, void *data)
{ {
PyObject *ret; PyObject *ret;
int type = RNA_property_type(prop); int type = RNA_property_type(prop);
@@ -2642,7 +2642,15 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
int a; int a;
if(RNA_property_array_check(ptr, prop)) { if(RNA_property_array_check(ptr, prop)) {
int len = RNA_property_array_length(ptr, prop); int len;
if (flag & PROP_DYNAMIC) {
len= RNA_parameter_length_get_data(parms, prop, data);
data= *((void **)data);
}
else
len= RNA_property_array_length(ptr, prop);
/* resolve the array from a new pytype */ /* resolve the array from a new pytype */
@@ -2819,7 +2827,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
flag= RNA_property_flag(parm); flag= RNA_property_flag(parm);
/* only useful for single argument returns, we'll need another list loop for multiple */ /* only useful for single argument returns, we'll need another list loop for multiple */
if (flag & PROP_RETURN) { if (flag & PROP_OUTPUT) {
ret_len++; ret_len++;
if (pret_single==NULL) { if (pret_single==NULL) {
pret_single= parm; pret_single= parm;
@@ -2856,7 +2864,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
continue; continue;
} }
err= pyrna_py_to_prop(&funcptr, parm, iter.data, item, ""); err= pyrna_py_to_prop(&funcptr, parm, &parms, iter.data, item, "");
if(err!=0) { if(err!=0) {
/* the error generated isnt that useful, so generate it again with a useful prefix /* the error generated isnt that useful, so generate it again with a useful prefix
@@ -2869,7 +2877,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
else else
snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with argument %d, \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), i, parm_id); snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with argument %d, \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), i, parm_id);
pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix); pyrna_py_to_prop(&funcptr, parm, &parms, iter.data, item, error_prefix);
break; break;
} }
@@ -2927,7 +2935,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
RNA_parameter_list_begin(&parms, &iter); RNA_parameter_list_begin(&parms, &iter);
for(; iter.valid; RNA_parameter_list_next(&iter)) { for(; iter.valid; RNA_parameter_list_next(&iter)) {
parm= iter.parm; parm= iter.parm;
if(RNA_property_flag(parm) & PROP_RETURN) if(RNA_property_flag(parm) & PROP_OUTPUT)
continue; continue;
BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm));
@@ -2974,14 +2982,14 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
parm= iter.parm; parm= iter.parm;
flag= RNA_property_flag(parm); flag= RNA_property_flag(parm);
if (flag & PROP_RETURN) if (flag & PROP_OUTPUT)
PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, &parms, parm, iter.data));
} }
RNA_parameter_list_end(&iter); RNA_parameter_list_end(&iter);
} }
else else
ret= pyrna_param_to_py(&funcptr, pret_single, retdata_single); ret= pyrna_param_to_py(&funcptr, &parms, pret_single, retdata_single);
/* possible there is an error in conversion */ /* possible there is an error in conversion */
if(ret==NULL) if(ret==NULL)
@@ -3724,7 +3732,7 @@ static int rna_function_arg_count(FunctionRNA *func)
for(link=lb->first; link; link=link->next) { for(link=lb->first; link; link=link->next) {
parm= (PropertyRNA*)link; parm= (PropertyRNA*)link;
if(!(RNA_property_flag(parm) & PROP_RETURN)) if(!(RNA_property_flag(parm) & PROP_OUTPUT))
count++; count++;
} }
@@ -3825,7 +3833,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if(strcmp(identifier, rna_attr) == 0) { \ if(strcmp(identifier, rna_attr) == 0) { \
item= PyObject_GetAttrString(py_class, py_attr); \ item= PyObject_GetAttrString(py_class, py_attr); \
if(item && item != Py_None) { \ if(item && item != Py_None) { \
if(pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class error:") != 0) { \ if(pyrna_py_to_prop(dummyptr, prop, NULL, NULL, item, "validating class error:") != 0) { \
Py_DECREF(item); \ Py_DECREF(item); \
return -1; \ return -1; \
} \ } \
@@ -3849,7 +3857,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
else { else {
Py_DECREF(item); /* no need to keep a ref, the class owns it */ Py_DECREF(item); /* no need to keep a ref, the class owns it */
if(pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class error:") != 0) if(pyrna_py_to_prop(dummyptr, prop, NULL, NULL, item, "validating class error:") != 0)
return -1; return -1;
} }
} }
@@ -3912,7 +3920,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
flag= RNA_property_flag(parm); flag= RNA_property_flag(parm);
/* only useful for single argument returns, we'll need another list loop for multiple */ /* only useful for single argument returns, we'll need another list loop for multiple */
if (flag & PROP_RETURN) { if (flag & PROP_OUTPUT) {
ret_len++; ret_len++;
if (pret_single==NULL) { if (pret_single==NULL) {
pret_single= parm; pret_single= parm;
@@ -3922,7 +3930,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
continue; continue;
} }
parmitem= pyrna_param_to_py(&funcptr, parm, iter.data); parmitem= pyrna_param_to_py(&funcptr, parms, parm, iter.data);
PyTuple_SET_ITEM(args, i, parmitem); PyTuple_SET_ITEM(args, i, parmitem);
i++; i++;
} }
@@ -3950,7 +3958,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
} }
else { else {
if(ret_len==1) { if(ret_len==1) {
err= pyrna_py_to_prop(&funcptr, pret_single, retdata_single, ret, "calling class function:"); err= pyrna_py_to_prop(&funcptr, pret_single, parms, retdata_single, ret, "calling class function:");
} }
else if (ret_len > 1) { else if (ret_len > 1) {
@@ -3972,8 +3980,8 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
flag= RNA_property_flag(parm); flag= RNA_property_flag(parm);
/* only useful for single argument returns, we'll need another list loop for multiple */ /* only useful for single argument returns, we'll need another list loop for multiple */
if (flag & PROP_RETURN) { if (flag & PROP_OUTPUT) {
err= pyrna_py_to_prop(&funcptr, parm, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); err= pyrna_py_to_prop(&funcptr, parm, parms, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:");
if(err) if(err)
break; break;
} }

View File

@@ -75,7 +75,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ); PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
/* operators also need this to set args */ /* operators also need this to set args */
int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix); int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, void *data, PyObject *value, const char *error_prefix);
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix); int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix);
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
@@ -92,7 +92,7 @@ void pyrna_alloc_types(void);
void pyrna_free_types(void); void pyrna_free_types(void);
/* primitive type conversion */ /* primitive type conversion */
int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix); int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, char *param_data, PyObject *py, const char *error_prefix);
int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix); int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix);
PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop); PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop);