RNA functions
authorElia Sarti <vekoon@gmail.com>
Sun, 24 Jan 2010 10:51:59 +0000 (10:51 +0000)
committerElia Sarti <vekoon@gmail.com>
Sun, 24 Jan 2010 10:51:59 +0000 (10:51 +0000)
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).

14 files changed:
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_action_api.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_rna.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/python/intern/bpy_array.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h

index 8a644b83938522e985f6621d5a7993eb090c689f..17d6436eeae24cb5ed32ae39fc8d94eb3e0b816d 100644 (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_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);
index f340834d93b0e9632ff8f01bf89bd330bc82a7a0..4bdb9f0862ce754fc9c74058c83116d287000124 100644 (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_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);
 
index ebb0a0b4c51cb85a25b23ef177e72208adb5f446..5480ebcf84479f5035698f8bd4f578dcf0dad2b9 100644 (file)
@@ -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,
index fe9caf26e1bb078a4700f2fa3b160983fbf31a8e..978ca0ba188954ada715fec8d914456a27589750 100644 (file)
@@ -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");
index 1fdbb3f9a15db4c7eb22f6622084d5dd316e88b0..cb3911b6423da03682929e0811e731dce591f6ae 100644 (file)
@@ -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;
                }
 
index 991a8251cc5e295e43eb1e077cde84fd6f0cd17f..f1f3800db42675b86fb6861e90c41be96f276daa 100644 (file)
 #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
index ed10c0819fd2d2e286f1a54bef9937ecfad2d189..d2036c61f61e6a167eafe3ccc53e6013652fb2c8 100644 (file)
@@ -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)
index 3d18804036a70dd093c9269a6b3a7b97d99eb4cf..5423c3eee3178c2e515ee7bcbb2d377a699e99ea 100644 (file)
@@ -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 */
 
index 8379ae7995da01cff15005883a1af701bcb19bab..6b62a8c7a0b5783c621d6e765903b9f9b270665a 100644 (file)
@@ -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 */
index 51f0fe62722e4fe1447247b6971fb7b94f6a3e14..d917d553fedf18afcb243e7be19182bfa72becce 100644 (file)
@@ -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)
index 84dc3e6971ef91979858f3dfe3359e5eb6cde6dd..cd23330557e5e5244ff051f50b83758303c04b90 100644 (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_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
index 5afcae8f2ed383dcf7be4a91a69c1dbd491d315e..e401ea55e4823ca1b139b5f97377037e53ae0fe3 100644 (file)
@@ -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");
index 49de1b3e944e76938ca929f15ae025221c10d5ab..f359dd9105dd34372ea2eb6a0d44ce34c2c90050 100644 (file)
@@ -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;
                                        }
index f7afeed05cefab2f9cfa548c85a6b9efd83c5b3a..284eef2c0e1630f812d9d5b6a052f0a27a596684 100644 (file)
@@ -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);