diff options
author | Elia Sarti <vekoon@gmail.com> | 2009-04-11 19:46:35 +0400 |
---|---|---|
committer | Elia Sarti <vekoon@gmail.com> | 2009-04-11 19:46:35 +0400 |
commit | c848ea953d6b10a74b334180220fb5ca3bd4f5bb (patch) | |
tree | 27eb33095c2c2bc59bc9d01cc2d08eb2fc651b10 /source/blender/makesrna/intern/rna_access.c | |
parent | a406c15d93cf8b69f75a34dce5f24a4ea03045c6 (diff) |
2.5 / RNA
API, added support for return values for RNA_function_call_direct and completed the code. Didn't test it though.
Returns works exact the same way as other parameters for format strings except you put a R in front of it. For instance for a function that accepts two vectors and returns a vector you use a format like "f[4]f[4]Rf[4]".
I'm thinking about allowing arbitrary white space in the format string (or use comas as separators) to make it more readable.
The return format *must* always come last and of course the corresponding argument you pass to the function has to be a pointer so that it can be filled with the return value.
Diffstat (limited to 'source/blender/makesrna/intern/rna_access.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 336 |
1 files changed, 212 insertions, 124 deletions
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 8ce8d945576..7b42d4afa60 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2367,6 +2367,145 @@ int RNA_function_call_direct_lookup(PointerRNA *ptr, const char *identifier, con return -1; } +static int rna_function_format_array_length(const char *format, int ofs, int flen) +{ + char lenbuf[16]; + int idx= 0; + + if (format[ofs++]=='[') + for (; ofs<flen && format[ofs]!=']' && idx<sizeof(*lenbuf)-1; idx++, ofs++) + lenbuf[idx]= format[ofs]; + + if (ofs<flen && format[ofs++]==']') { + /* XXX put better error reporting for ofs>=flen or idx over lenbuf capacity */ + lenbuf[idx]= '\0'; + return atoi(lenbuf); + } + + return 0; +} + +static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, PropertyType type, char ftype, int len, void *dest, void *src, StructRNA *srna, const char *tid, const char *fid, const char *pid) +{ + /* ptr is always a function pointer, prop always a parameter */ + + switch (type) { + case PROP_BOOLEAN: + { + if (ftype!='b') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, a boolean was expected\n", tid, fid, pid); + return -1; + } + + if (len==0) + *((int*)dest)= *((int*)src); + else + memcpy(dest, src, len*sizeof(int)); + + break; + } + case PROP_INT: + { + if (ftype!='i') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, an integer was expected\n", tid, fid, pid); + return -1; + } + + if (len==0) + *((int*)dest)= *((int*)src); + else + memcpy(dest, src, len*sizeof(int)); + + break; + } + case PROP_FLOAT: + { + if (ftype!='f') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, a float was expected\n", tid, fid, pid); + return -1; + } + + if (len==0) + *((float*)dest)= *((float*)src); + else + memcpy(dest, src, len*sizeof(float)); + + break; + } + case PROP_STRING: + { + if (ftype!='s') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, a string was expected\n", tid, fid, pid); + return -1; + } + + *((char**)dest)= *((char**)src); + + break; + } + case PROP_ENUM: + { + if (ftype!='e') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, an enum was expected\n", tid, fid, pid); + return -1; + } + + *((int*)dest)= *((int*)src); + + break; + } + case PROP_POINTER: + { + StructRNA *ptype; + + if (ftype!='O') { + fprintf(stderr, "%s.%s: wrong type for parameter %s, an object was expected\n", tid, fid, pid); + return -1; + } + + ptype= RNA_property_pointer_type(ptr, prop); + + if(ptype == &RNA_AnyType) { + *((PointerRNA*)dest)= *((PointerRNA*)src); + } + else if (ptype!=srna) { + PointerRNA pptr; + + RNA_pointer_create(NULL, srna, *((void**)src), &pptr); + + if (!RNA_struct_is_a(&pptr, ptype)) { + PointerRNA tmp; + RNA_pointer_create(NULL, ptype, NULL, &tmp); + + fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(&tmp), RNA_struct_identifier(&pptr)); + return -1; + } + + *((void**)dest)= *((void**)src); + } + + break; + } + case PROP_COLLECTION: + { + /* XXX collections are not supported yet */ + fprintf(stderr, "%s.%s: for parameter %s, collections are not supported yet\n", tid, fid, pid); + return -1; + } + default: + { + if (len==0) + fprintf(stderr, "%s.%s: unknown type for parameter %s\n", tid, fid, pid); + else + fprintf(stderr, "%s.%s: unknown array type for parameter %s\n", tid, fid, pid); + + return -1; + } + } + + return 0; +} + int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args) { PointerRNA funcptr; @@ -2376,7 +2515,7 @@ int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char * PropertyType type; int i, ofs, flen, flag, len, alen, err= 0; const char *tid, *fid, *pid; - char ftype, lenbuf[16]; + char ftype; void **retdata; RNA_pointer_create(NULL, &RNA_Function, func, &funcptr); @@ -2411,153 +2550,48 @@ int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char * } type= RNA_property_type(&funcptr, parm); - len= RNA_property_array_length(&funcptr, parm); - alen= 0; ftype= format[ofs++]; - - if (len>0) { - int idx= 0; - - if (format[ofs++]=='[') - for (; ofs<flen && format[ofs]!=']' && idx<sizeof(*lenbuf)-1; idx++, ofs++) - lenbuf[idx]= format[ofs]; - - if (ofs<flen && format[ofs++]==']') { - /* XXX put better error reporting for ofs>=flen or idx over lenbuf capacity */ - lenbuf[idx]= '\0'; - alen= atoi(lenbuf); - } - } + len= RNA_property_array_length(&funcptr, parm); + alen= rna_function_format_array_length(format, ofs, flen); if (len!=alen) { err= -1; fprintf(stderr, "%s.%s: for parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen); break; } - + switch (type) { case PROP_BOOLEAN: - { - if (format[ofs]!='b') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, a boolean was expected\n", tid, fid, pid); - break; - } - - if (len==0) - *((int*)iter.data)= va_arg(args, int); - else - memcpy(iter.data, va_arg(args, int*), len); - - break; - } case PROP_INT: + case PROP_ENUM: { - if (format[ofs]!='i') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, an integer was expected\n", tid, fid, pid); - break; - } - - if (len==0) - *((int*)iter.data)= va_arg(args, int); - else - memcpy(iter.data, va_arg(args, int*), len); - + int arg= va_arg(args, int); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid); break; } case PROP_FLOAT: { - if (format[ofs]!='f') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, a float was expected\n", tid, fid, pid); - break; - } - - if (len==0) - *((float*)iter.data)= va_arg(args, float); - else - memcpy(iter.data, va_arg(args, float*), len); - + float arg= va_arg(args, float); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid); break; } case PROP_STRING: { - if (format[ofs]!='s') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, a string was expected\n", tid, fid, pid); - break; - } - - *((char**)iter.data)= va_arg(args, char*); - - break; - } - case PROP_ENUM: - { - if (format[ofs]!='e') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, an enum was expected\n", tid, fid, pid); - break; - } - - *((int*)iter.data)= va_arg(args, int); - + char *arg= va_arg(args, char*); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid); break; } case PROP_POINTER: { - StructRNA *ptype, *srna; - void *data; - - if (format[ofs]!='O') { - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, an object was expected\n", tid, fid, pid); - break; - } - - ptype= RNA_property_pointer_type(&funcptr, parm); - /* for objects we use two parms: the first is the type and the second is the data */ - srna= va_arg(args, StructRNA*); - - if(ptype == &RNA_AnyType) { - *((PointerRNA*)iter.data)= va_arg(args, PointerRNA); - } - else if (ptype!=srna) { - PointerRNA pptr; - - data= va_arg(args, void*); - RNA_pointer_create(NULL, srna, data, &pptr); - - if (!RNA_struct_is_a(&pptr, ptype)) { - PointerRNA tmp; - RNA_pointer_create(NULL, ptype, NULL, &tmp); - - err= -1; - fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(&tmp), RNA_struct_identifier(&pptr)); - break; - } - - *((void**)iter.data)= data; - } - - break; - } - case PROP_COLLECTION: - { - /* XXX collections are not supported yet */ - err= -1; - fprintf(stderr, "%s.%s: for parameter %s, collections are not supported yet\n", tid, fid, pid); + StructRNA *srna= va_arg(args, StructRNA*); + void *arg= va_arg(args, void*); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid); break; } - default: + default: { - err= -1; - if (len==0) - fprintf(stderr, "%s.%s: unknown type for parameter %s\n", tid, fid, pid); - else - fprintf(stderr, "%s.%s: unknown array type for parameter %s\n", tid, fid, pid); - + /* handle errors */ + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, NULL, NULL, tid, fid, pid); break; } } @@ -2566,10 +2600,64 @@ int RNA_function_call_direct_va(PointerRNA *ptr, FunctionRNA *func, const char * break; } - if (err==0 && pret) { - /* XXX return values still not implemented */ + if (err==0) + err= RNA_function_call(ptr, func, parms); + + /* XXX throw error when more parameters than those needed are passed or leave silent? */ + if (err==0 && pret && ofs<flen && format[ofs++]=='R') { + parm= pret; + + type= RNA_property_type(&funcptr, parm); + ftype= format[ofs++]; + len= RNA_property_array_length(&funcptr, parm); + alen= rna_function_format_array_length(format, ofs, flen); + + if (len!=alen) { + err= -1; + fprintf(stderr, "%s.%s: for return parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen); + } + else { + switch (type) { + case PROP_BOOLEAN: + case PROP_INT: + case PROP_ENUM: + { + int *arg= va_arg(args, int*); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid); + break; + } + case PROP_FLOAT: + { + float *arg= va_arg(args, float*); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid); + break; + } + case PROP_STRING: + { + char **arg= va_arg(args, char**); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid); + break; + } + case PROP_POINTER: + { + StructRNA *srna= va_arg(args, StructRNA*); + void **arg= va_arg(args, void**); + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid); + break; + } + default: + { + /* handle errors */ + err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, NULL, NULL, NULL, tid, fid, pid); + break; + } + } + } } + RNA_parameter_list_end(&iter); + RNA_parameter_list_free(parms); + return err; } |