[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26223] trunk/blender/source/blender: RNA functions

Elia Sarti vekoon at gmail.com
Sun Jan 24 11:51:59 CET 2010


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. @@




More information about the Bf-blender-cvs mailing list