diff options
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 4 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_define.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 121 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 61 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_action_api.c | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_define.c | 30 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_rna.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene_api.c | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_array.c | 12 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 54 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 4 |
14 files changed, 220 insertions, 100 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 8a644b83938..17d6436eeae 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -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_set(ParameterList *parms, PropertyRNA *parm, 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_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index f340834d93b..4bdb9f0862c 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -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_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_output(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/RNA_types.h b/source/blender/makesrna/RNA_types.h index ebb0a0b4c51..5480ebcf844 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -150,7 +150,7 @@ typedef enum PropertyFlag { /* function paramater flags */ PROP_REQUIRED = 1<<2, - PROP_RETURN = 1<<3, + PROP_OUTPUT = 1<<3, PROP_RNAPTR = 1<<11, /* registering */ PROP_REGISTER = 1<<4, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index fe9caf26e1b..978ca0ba188 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1290,8 +1290,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA StructRNA *srna; FunctionRNA *func; PropertyDefRNA *dparm; - char *funcname, *ptrstr; - int first; + PropertyType type; + char *funcname, *ptrstr, *valstr; + int flag, pout, cptr, first; srna= dsrna->srna; func= dfunc->func; @@ -1316,19 +1317,30 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= dfunc->cont.properties.first; 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= "*"; - 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)) { - if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING)) - ptrstr= ""; - else - ptrstr= ((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR))? "**": "*"; - } else - ptrstr= (dparm->prop->type == PROP_POINTER)? "*": ""; + /* 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)) + ptrstr= ""; + else + ptrstr= pout ? "*" : ""; 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"); @@ -1349,30 +1361,45 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA dparm= dfunc->cont.properties.first; for(; dparm; dparm= dparm->next) { - if ((dparm->prop->flag & PROP_RETURN)) - ptrstr= ""; - else - ptrstr= "*"; + 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) 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)); - else if(dparm->prop->type == PROP_POINTER) { - 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%s**)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); - } - else { - if ((dparm->prop->flag & PROP_THICK_WRAP) && (dparm->prop->type == PROP_STRING)) - 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%s*)_data);\n", dparm->prop->identifier, ptrstr, rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop)); + else { + if (cptr || (flag & PROP_DYNAMIC)) { + ptrstr= "**"; + valstr= "*"; + } + else if (type == PROP_POINTER || dparm->prop->arraydimension) { + ptrstr= "*"; + valstr= ""; + } + else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) { + ptrstr= ""; + valstr= ""; + } + 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) - 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) { @@ -1412,6 +1439,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA first= 0; fprintf(f, "%s", dparm->prop->identifier); + + if (dparm->prop->flag & PROP_DYNAMIC) + fprintf(f, ", %s_len", dparm->prop->identifier); } fprintf(f, ");\n"); @@ -1653,7 +1683,8 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA FunctionRNA *func; PropertyDefRNA *dparm; StructDefRNA *dsrna; - int first; + PropertyType type; + int flag, pout, cptr, first; char *ptrstr; dsrna= rna_find_struct_def(srna); @@ -1706,25 +1737,33 @@ static void rna_generate_static_parameter_prototypes(BlenderRNA *brna, StructRNA /* defined parameters */ 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) continue; - if(!first) fprintf(f, ", "); - first= 0; - - if((dparm->prop->type == PROP_STRING && dparm->prop->flag & PROP_THICK_WRAP)) - ptrstr= ""; - else if(dparm->prop->flag & PROP_RETURN) + if (cptr || (flag & PROP_DYNAMIC)) + ptrstr= pout ? "**" : "*"; + else if (type == PROP_POINTER || dparm->prop->arraydimension) ptrstr= "*"; - else + else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) ptrstr= ""; + else + ptrstr= pout ? "*" : ""; - if(dparm->prop->arraydimension) + if(!first) fprintf(f, ", "); + first= 0; + + if(!(flag & PROP_DYNAMIC) && 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%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%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"); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 1fdbb3f9a15..cb3911b6423 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3603,7 +3603,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, /* allocate data */ 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->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; @@ -3666,7 +3670,7 @@ void RNA_parameter_list_free(ParameterList *parms) MEM_freeN(array); } - tot+= rna_parameter_size(parm); + tot+= rna_parameter_size_alloc(parm); } MEM_freeN(parms->data); @@ -3692,7 +3696,7 @@ void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter) iter->offset= 0; 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); ptype= RNA_property_type(iter->parm); } @@ -3707,7 +3711,7 @@ void RNA_parameter_list_next(ParameterIterator *iter) iter->valid= iter->parm != NULL; 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); 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); } +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) { if(func->call) { @@ -4022,7 +4071,7 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt retdata= iter.data; continue; } - else if (flag & PROP_RETURN) { + else if (flag & PROP_OUTPUT) { continue; } diff --git a/source/blender/makesrna/intern/rna_action_api.c b/source/blender/makesrna/intern/rna_action_api.c index 991a8251cc5..f1f3800db42 100644 --- a/source/blender/makesrna/intern/rna_action_api.c +++ b/source/blender/makesrna/intern/rna_action_api.c @@ -41,40 +41,35 @@ #include "DNA_anim_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 */ -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; float start, end; calc_action_range(act, &start, &end, 1); - *ret_length= 2; - ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range"); + *length_r= 2; + ret= MEM_callocN(*length_r * sizeof(int), "rna_Action_get_frame_range"); ret[0]= (int)start; ret[1]= (int)end; - - return ret; + + *frame_range= ret; } -#endif #else void RNA_api_action(StructRNA *srna) { -#if 0 FunctionRNA *func; PropertyRNA *parm; 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."); 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_function_return(func, parm); -#endif + RNA_def_property_flag(parm, PROP_DYNAMIC); + RNA_def_function_output(func, parm); } #endif diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index ed10c0819fd..d2036c61f61 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2419,17 +2419,26 @@ 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 */ +/* C return value only!, multiple RNA returns can be done with RNA_def_function_output */ 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; - 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) @@ -2448,6 +2457,7 @@ int rna_parameter_size(PropertyRNA *parm) int len= parm->totarraylength; /* only supports fixed length at the moment */ if(len > 0) { + /* XXX in other parts is mentioned that strings can be dynamic as well */ if (parm->flag & PROP_DYNAMIC) return sizeof(void *); @@ -2497,6 +2507,18 @@ int rna_parameter_size(PropertyRNA *parm) 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 */ void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item) diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 3d18804036a..5423c3eee31 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -331,6 +331,7 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA * /* Functions */ int rna_parameter_size(struct PropertyRNA *parm); +int rna_parameter_size_alloc(struct PropertyRNA *parm); #endif /* RNA_INTERNAL_H */ diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 8379ae7995d..6b62a8c7a0b 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -497,13 +497,13 @@ void RNA_api_object(StructRNA *srna) /* 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); 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); 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); - RNA_def_function_return_mark(func, parm); + RNA_def_function_output(func, parm); /* DAG */ diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 51f0fe62722..d917d553fed 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -439,7 +439,7 @@ static int rna_Property_readonly_get(PointerRNA *ptr) static int rna_Property_use_return_get(PointerRNA *ptr) { 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) diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 84dc3e6971e..cd23330557e 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -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_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_function_return_mark(func, parm); + RNA_def_function_output(func, parm); } #endif diff --git a/source/blender/python/intern/bpy_array.c b/source/blender/python/intern/bpy_array.c index 5afcae8f2ed..e401ea55e48 100644 --- a/source/blender/python/intern/bpy_array.c +++ b/source/blender/python/intern/bpy_array.c @@ -242,7 +242,7 @@ static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int 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 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) { /* not freeing allocated mem, RNA_parameter_list_free will do this */ *(char**)param_data= data; + + RNA_parameter_length_set_data(parms, prop, param_data, totitem); } } 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); } -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; switch (RNA_property_type(prop)) { 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; 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; 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; default: PyErr_SetString(PyExc_TypeError, "not an array type"); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 49de1b3e944..f359dd9105d 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -593,7 +593,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha break; } } 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; 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 */ 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; } /* 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) { /* 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 * however so many poll functions return None or a valid Object. * 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 ); else 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 */ - 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) @@ -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 ((prop = RNA_struct_find_property(&r_ptr, name))) { /* 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; int type = RNA_property_type(prop); @@ -2642,7 +2642,15 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) int a; 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 */ @@ -2819,7 +2827,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) flag= RNA_property_flag(parm); /* only useful for single argument returns, we'll need another list loop for multiple */ - if (flag & PROP_RETURN) { + if (flag & PROP_OUTPUT) { ret_len++; if (pret_single==NULL) { pret_single= parm; @@ -2856,7 +2864,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) 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) { /* 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 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; } @@ -2927,7 +2935,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw) RNA_parameter_list_begin(&parms, &iter); for(; iter.valid; RNA_parameter_list_next(&iter)) { parm= iter.parm; - if(RNA_property_flag(parm) & PROP_RETURN) + if(RNA_property_flag(parm) & PROP_OUTPUT) continue; 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; flag= RNA_property_flag(parm); - if (flag & PROP_RETURN) - PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); + if (flag & PROP_OUTPUT) + PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, &parms, parm, iter.data)); } RNA_parameter_list_end(&iter); } 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 */ if(ret==NULL) @@ -3724,7 +3732,7 @@ static int rna_function_arg_count(FunctionRNA *func) for(link=lb->first; link; link=link->next) { parm= (PropertyRNA*)link; - if(!(RNA_property_flag(parm) & PROP_RETURN)) + if(!(RNA_property_flag(parm) & PROP_OUTPUT)) count++; } @@ -3825,7 +3833,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun if(strcmp(identifier, rna_attr) == 0) { \ item= PyObject_GetAttrString(py_class, py_attr); \ 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); \ return -1; \ } \ @@ -3849,7 +3857,7 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun else { 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; } } @@ -3912,7 +3920,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par flag= RNA_property_flag(parm); /* only useful for single argument returns, we'll need another list loop for multiple */ - if (flag & PROP_RETURN) { + if (flag & PROP_OUTPUT) { ret_len++; if (pret_single==NULL) { pret_single= parm; @@ -3922,7 +3930,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par 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); i++; } @@ -3950,7 +3958,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par } else { 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) { @@ -3972,8 +3980,8 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par 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 (flag & PROP_OUTPUT) { + err= pyrna_py_to_prop(&funcptr, parm, parms, iter.data, PyTuple_GET_ITEM(ret, i++), "calling class function:"); if(err) break; } diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index f7afeed05ce..284eef2c0e1 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -75,7 +75,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr ); PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop ); /* 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); PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); @@ -92,7 +92,7 @@ void pyrna_alloc_types(void); void pyrna_free_types(void); /* 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); PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop); |