Revision: 26223
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26223
Author:   vekoon
Date:     2010-01-24 11:51:59 +0100 (Sun, 24 Jan 2010)

Log Message:
-----------
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).

Modified Paths:
--------------
    trunk/blender/source/blender/makesrna/RNA_access.h
    trunk/blender/source/blender/makesrna/RNA_define.h
    trunk/blender/source/blender/makesrna/RNA_types.h
    trunk/blender/source/blender/makesrna/intern/makesrna.c
    trunk/blender/source/blender/makesrna/intern/rna_access.c
    trunk/blender/source/blender/makesrna/intern/rna_action_api.c
    trunk/blender/source/blender/makesrna/intern/rna_define.c
    trunk/blender/source/blender/makesrna/intern/rna_internal.h
    trunk/blender/source/blender/makesrna/intern/rna_object_api.c
    trunk/blender/source/blender/makesrna/intern/rna_rna.c
    trunk/blender/source/blender/makesrna/intern/rna_scene_api.c
    trunk/blender/source/blender/python/intern/bpy_array.c
    trunk/blender/source/blender/python/intern/bpy_rna.c
    trunk/blender/source/blender/python/intern/bpy_rna.h

Modified: trunk/blender/source/blender/makesrna/RNA_access.h
===================================================================
--- trunk/blender/source/blender/makesrna/RNA_access.h  2010-01-24 10:18:16 UTC 
(rev 26222)
+++ trunk/blender/source/blender/makesrna/RNA_access.h  2010-01-24 10:51:59 UTC 
(rev 26223)
@@ -886,6 +886,10 @@
 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);

Modified: trunk/blender/source/blender/makesrna/RNA_define.h
===================================================================
--- trunk/blender/source/blender/makesrna/RNA_define.h  2010-01-24 10:18:16 UTC 
(rev 26222)
+++ trunk/blender/source/blender/makesrna/RNA_define.h  2010-01-24 10:51:59 UTC 
(rev 26223)
@@ -172,7 +172,7 @@
 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);
 

Modified: trunk/blender/source/blender/makesrna/RNA_types.h
===================================================================
--- trunk/blender/source/blender/makesrna/RNA_types.h   2010-01-24 10:18:16 UTC 
(rev 26222)
+++ trunk/blender/source/blender/makesrna/RNA_types.h   2010-01-24 10:51:59 UTC 
(rev 26223)
@@ -150,7 +150,7 @@
 
        /* function paramater flags */
        PROP_REQUIRED = 1<<2,
-       PROP_RETURN = 1<<3,
+       PROP_OUTPUT = 1<<3,
        PROP_RNAPTR = 1<<11,
        /* registering */
        PROP_REGISTER = 1<<4,

Modified: trunk/blender/source/blender/makesrna/intern/makesrna.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/makesrna.c     2010-01-24 
10:18:16 UTC (rev 26222)
+++ trunk/blender/source/blender/makesrna/intern/makesrna.c     2010-01-24 
10:51:59 UTC (rev 26223)
@@ -1290,8 +1290,9 @@
        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 @@
 
        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 @@
 
        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 (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));
                }
-               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));
-               }
 
                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 @@
                        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 @@
        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 @@
 
        /* 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 (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, ", ");
                first= 0;
 
-               if((dparm->prop->type == PROP_STRING && dparm->prop->flag & 
PROP_THICK_WRAP))
-                       ptrstr= "";
-               else if(dparm->prop->flag & PROP_RETURN)
-                       ptrstr= "*";
-               else
-                       ptrstr= "";
-
-               if(dparm->prop->arraydimension)
+               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");

Modified: trunk/blender/source/blender/makesrna/intern/rna_access.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_access.c   2010-01-24 
10:18:16 UTC (rev 26222)
+++ trunk/blender/source/blender/makesrna/intern/rna_access.c   2010-01-24 
10:51:59 UTC (rev 26223)
@@ -3603,7 +3603,7 @@
 
        /* 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 @@
                        }
                }
 
-               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 @@
                                MEM_freeN(array);
                }
 
-               tot+= rna_parameter_size(parm);
+               tot+= rna_parameter_size_alloc(parm);
        }
 
        MEM_freeN(parms->data);
@@ -3692,7 +3696,7 @@
        iter->offset= 0;
 
        if(iter->valid) {

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to