Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/makesrna/intern/rna_access.c')
-rw-r--r--source/blender/makesrna/intern/rna_access.c377
1 files changed, 366 insertions, 11 deletions
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7defb0676c6..cc8704dc350 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1522,6 +1522,323 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co
}
}
+int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
+{
+ CollectionPropertyIterator iter;
+ ArrayIterator *internal;
+ char *arrayp;
+
+ if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
+ return 0;
+
+ RNA_property_collection_begin(ptr, prop, &iter);
+
+ if(iter.valid) {
+ /* get data from array iterator and item property */
+ internal= iter.internal;
+ arrayp= (iter.valid)? iter.ptr.data: NULL;
+
+ if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
+ /* we might skip some items, so it's not a proper array */
+ RNA_property_collection_end(&iter);
+ return 0;
+ }
+
+ array->array= arrayp + itemprop->rawoffset;
+ array->stride= internal->itemsize;
+ array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
+ array->type= itemprop->rawtype;
+ }
+ else
+ memset(array, 0, sizeof(RawArray));
+
+ RNA_property_collection_end(&iter);
+
+ return 1;
+}
+
+#define RAW_GET(dtype, var, raw, a) \
+{ \
+ switch(raw.type) { \
+ case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
+ case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
+ case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
+ case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
+ case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
+ default: var = (dtype)0; \
+ } \
+}
+
+#define RAW_SET(dtype, raw, a, var) \
+{ \
+ switch(raw.type) { \
+ case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
+ case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
+ case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
+ case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
+ case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
+ } \
+}
+
+int RNA_raw_type_sizeof(RawPropertyType type)
+{
+ switch(type) {
+ case PROP_RAW_CHAR: return sizeof(char);
+ case PROP_RAW_SHORT: return sizeof(short);
+ case PROP_RAW_INT: return sizeof(int);
+ case PROP_RAW_FLOAT: return sizeof(float);
+ case PROP_RAW_DOUBLE: return sizeof(double);
+ default: return 0;
+ }
+}
+
+static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
+{
+ StructRNA *ptype;
+ PointerRNA itemptr;
+ PropertyRNA *itemprop, *iprop;
+ PropertyType itemtype;
+ RawArray in;
+ int itemlen= 0;
+
+ /* initialize in array, stride assumed 0 in following code */
+ in.array= inarray;
+ in.type= intype;
+ in.len= inlen;
+ in.stride= 0;
+
+ ptype= RNA_property_pointer_type(ptr, prop);
+
+ /* try to get item property pointer */
+ RNA_pointer_create(NULL, ptype, NULL, &itemptr);
+ itemprop= RNA_struct_find_property(&itemptr, propname);
+
+ if(itemprop) {
+ /* we have item property pointer */
+ RawArray out;
+
+ /* check type */
+ itemtype= RNA_property_type(itemprop);
+
+ if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
+ BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
+ return 0;
+ }
+
+ /* check item array */
+ itemlen= RNA_property_array_length(itemprop);
+
+ /* try to access as raw array */
+ if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
+ if(in.len != itemlen*out.len) {
+ BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
+ return 0;
+ }
+
+ /* matching raw types */
+ if(out.type == in.type) {
+ void *inp= in.array;
+ void *outp= out.array;
+ int a, size;
+
+ itemlen= (itemlen == 0)? 1: itemlen;
+ size= RNA_raw_type_sizeof(out.type) * itemlen;
+
+ for(a=0; a<out.len; a++) {
+ if(set) memcpy(outp, inp, size);
+ else memcpy(inp, outp, size);
+
+ inp= (char*)inp + size;
+ outp= (char*)outp + out.stride;
+ }
+
+ return 1;
+ }
+
+ /* could also be faster with non-matching types,
+ * for now we just do slower loop .. */
+ }
+ }
+
+ {
+ void *tmparray= NULL;
+ int tmplen= 0;
+ int err= 0, j, a= 0;
+
+ /* no item property pointer, can still be id property, or
+ * property of a type derived from the collection pointer type */
+ RNA_PROP_BEGIN(ptr, itemptr, prop) {
+ if(itemptr.data) {
+ if(itemprop) {
+ /* we got the property already */
+ iprop= itemprop;
+ }
+ else {
+ /* not yet, look it up and verify if it is valid */
+ iprop= RNA_struct_find_property(&itemptr, propname);
+
+ if(iprop) {
+ itemlen= RNA_property_array_length(iprop);
+ itemtype= RNA_property_type(iprop);
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Property named %s not found.", propname);
+ err= 1;
+ break;
+ }
+
+ if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
+ BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
+ err= 1;
+ break;
+ }
+ }
+
+ /* editable check */
+ if(RNA_property_editable(&itemptr, iprop)) {
+ if(a+itemlen > in.len) {
+ BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
+ err= 1;
+ break;
+ }
+
+ if(itemlen == 0) {
+ /* handle conversions */
+ if(set) {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ int b;
+ RAW_GET(int, b, in, a);
+ RNA_property_boolean_set(&itemptr, iprop, b);
+ break;
+ }
+ case PROP_INT: {
+ int i;
+ RAW_GET(int, i, in, a);
+ RNA_property_int_set(&itemptr, iprop, i);
+ break;
+ }
+ case PROP_FLOAT: {
+ float f;
+ RAW_GET(float, f, in, a);
+ RNA_property_float_set(&itemptr, iprop, f);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ int b= RNA_property_boolean_get(&itemptr, iprop);
+ RAW_SET(int, in, a, b);
+ break;
+ }
+ case PROP_INT: {
+ int i= RNA_property_int_get(&itemptr, iprop);
+ RAW_SET(int, in, a, i);
+ break;
+ }
+ case PROP_FLOAT: {
+ float f= RNA_property_float_get(&itemptr, iprop);
+ RAW_SET(float, in, a, f);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ a++;
+ }
+ else {
+ /* allocate temporary array if needed */
+ if(tmparray && tmplen != itemlen) {
+ MEM_freeN(tmparray);
+ tmparray= NULL;
+ }
+ if(!tmparray) {
+ tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
+ tmplen= itemlen;
+ }
+
+ /* handle conversions */
+ if(set) {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ for(j=0; j<itemlen; j++, a++)
+ RAW_GET(int, ((int*)tmparray)[j], in, a);
+ RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
+ break;
+ }
+ case PROP_INT: {
+ for(j=0; j<itemlen; j++, a++)
+ RAW_GET(int, ((int*)tmparray)[j], in, a);
+ RNA_property_int_set_array(&itemptr, iprop, tmparray);
+ break;
+ }
+ case PROP_FLOAT: {
+ for(j=0; j<itemlen; j++, a++)
+ RAW_GET(float, ((float*)tmparray)[j], in, a);
+ RNA_property_float_set_array(&itemptr, iprop, tmparray);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else {
+ switch(itemtype) {
+ case PROP_BOOLEAN: {
+ RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
+ for(j=0; j<itemlen; j++, a++)
+ RAW_SET(int, in, a, ((int*)tmparray)[j]);
+ break;
+ }
+ case PROP_INT: {
+ RNA_property_int_get_array(&itemptr, iprop, tmparray);
+ for(j=0; j<itemlen; j++, a++)
+ RAW_SET(int, in, a, ((int*)tmparray)[j]);
+ break;
+ }
+ case PROP_FLOAT: {
+ RNA_property_float_get_array(&itemptr, iprop, tmparray);
+ for(j=0; j<itemlen; j++, a++)
+ RAW_SET(float, in, a, ((float*)tmparray)[j]);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ RNA_PROP_END;
+
+ if(tmparray)
+ MEM_freeN(tmparray);
+
+ return !err;
+ }
+}
+
+RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
+{
+ return prop->rawtype;
+}
+
+int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+ return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
+}
+
+int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
+{
+ return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
+}
+
/* Standard iterator functions */
void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
@@ -2733,23 +3050,46 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
if(prop->flag & PROP_RNAPTR) {
*((PointerRNA*)dest)= *((PointerRNA*)src);
+ break;
+ }
+
+ if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+ 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(ptype), RNA_struct_identifier(srna));
+ return -1;
}
- else if (ptype!=srna) {
- if (!RNA_struct_is_a(srna, ptype)) {
- 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(ptype), RNA_struct_identifier(ptype));
- return -1;
- }
-
- *((void**)dest)= *((void**)src);
- }
+
+ *((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;
+ StructRNA *ptype;
+ ListBase *lb, *clb;
+ Link *link;
+ CollectionPointerLink *clink;
+
+ if (ftype!='C') {
+ fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection was expected\n", tid, fid, pid);
+ return -1;
+ }
+
+ lb= (ListBase *)src;
+ clb= (ListBase *)dest;
+ ptype= RNA_property_pointer_type(ptr, prop);
+
+ if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
+ fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection of objects of type %s was expected, passed a collection of objects of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
+ return -1;
+ }
+
+ for (link= lb->first; link; link= link->next) {
+ clink= MEM_callocN(sizeof(CollectionPointerLink), "CCollectionPointerLink");
+ RNA_pointer_create(NULL, srna, link, &clink->ptr);
+ BLI_addtail(clb, clink);
+ }
+
+ break;
}
default:
{
@@ -2847,6 +3187,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
break;
}
+ case PROP_COLLECTION:
+ {
+ StructRNA *srna= va_arg(args, StructRNA*);
+ ListBase *arg= va_arg(args, ListBase*);
+ err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
+ break;
+ }
default:
{
/* handle errors */
@@ -2904,6 +3251,13 @@ int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *pt
err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
break;
}
+ case PROP_COLLECTION:
+ {
+ StructRNA *srna= va_arg(args, StructRNA*);
+ ListBase **arg= va_arg(args, ListBase**);
+ err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
+ break;
+ }
default:
{
/* handle errors */
@@ -2932,3 +3286,4 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer
return 0;
}
+