diff options
author | Bastien Montagne <bastien@blender.org> | 2020-07-10 16:19:40 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-07-10 16:19:40 +0300 |
commit | 337e2c902930d8a8980505d66234bc46c95b051c (patch) | |
tree | d34a163fcdd1fc06dd85fdefcafa97f4a6abf89a /source/blender/makesrna/intern/rna_access.c | |
parent | 6c1157201a143574c005147367bb2fd4ab320e73 (diff) |
RNA: refactor how we get 'ensured' RNA properties.
Introduce new PropertyRNAOrID structure, storing most useful data about
an 'opaque' PropertyRNA in relation with a given PointerRNA struct.
It deals with all the three cases (pure static RNA, runtime RNA where
data is actually stored in IDProperties, and pure IDProperties, aka
custom data.
Diffstat (limited to 'source/blender/makesrna/intern/rna_access.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 79 |
1 files changed, 61 insertions, 18 deletions
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 79cf993e0cc..c3b417ca79d 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -558,9 +558,12 @@ static PropertyRNA *arraytypemap[IDP_NUMTYPES] = { (PropertyRNA *)&rna_PropertyGroupItem_double_array, }; -static void *rna_idproperty_check_ex(PropertyRNA **prop, - PointerRNA *ptr, - const bool return_rnaprop) +/* This function initializes a PropertyRNAOrID with all required info, from a given PropertyRNA + * and PointerRNA data. It deals properly with the three cases (static RNA, runtime RNA, and + * IDProperty). */ +void rna_property_rna_or_id_get(PropertyRNA *prop, + PointerRNA *ptr, + PropertyRNAOrID *r_prop_rna_or_id) { /* This is quite a hack, but avoids some complexity in the API. we * pass IDProperty structs as PropertyRNA pointers to the outside. @@ -568,36 +571,64 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop, * distinguish it from IDProperty structs. If it is an ID property, * we look up an IDP PropertyRNA based on the type, and set the data * pointer to the IDProperty. */ + memset(r_prop_rna_or_id, 0, sizeof(*r_prop_rna_or_id)); - if ((*prop)->magic == RNA_MAGIC) { - if ((*prop)->flag & PROP_IDPROPERTY) { - IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier); + r_prop_rna_or_id->ptr = *ptr; + r_prop_rna_or_id->rawprop = prop; - if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) { + if (prop->magic == RNA_MAGIC) { + r_prop_rna_or_id->rnaprop = prop; + r_prop_rna_or_id->identifier = prop->identifier; + + r_prop_rna_or_id->is_array = prop->getlength || prop->totarraylength; + if (r_prop_rna_or_id->is_array) { + int arraylen[RNA_MAX_ARRAY_DIMENSION]; + r_prop_rna_or_id->array_len = (prop->getlength && ptr->data) ? + (uint)prop->getlength(ptr, arraylen) : + prop->totarraylength; + } + + if (prop->flag & PROP_IDPROPERTY) { + IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier); + + if (idprop != NULL && !rna_idproperty_verify_valid(ptr, prop, idprop)) { IDProperty *group = RNA_struct_idprops(ptr, 0); IDP_FreeFromGroup(group, idprop); - return NULL; + idprop = NULL; } - return idprop; + r_prop_rna_or_id->idprop = idprop; + r_prop_rna_or_id->is_set = idprop != NULL && (idprop->flag & IDP_FLAG_GHOST) == 0; } else { - return return_rnaprop ? *prop : NULL; + /* Full static RNA properties are always set. */ + r_prop_rna_or_id->is_set = true; } } + else { + IDProperty *idprop = (IDProperty *)prop; + /* Given prop may come from the custom properties of another data, ensure we get the one from + * given data ptr. */ + IDProperty *idprop_evaluated = rna_idproperty_find(ptr, idprop->name); + if (idprop_evaluated != NULL && idprop->type != idprop_evaluated->type) { + idprop_evaluated = NULL; + } - { - IDProperty *idprop = (IDProperty *)(*prop); + r_prop_rna_or_id->idprop = idprop_evaluated; + r_prop_rna_or_id->is_idprop = true; + /* Full IDProperties are always set. */ + r_prop_rna_or_id->is_set = true; + r_prop_rna_or_id->identifier = idprop->name; if (idprop->type == IDP_ARRAY) { - *prop = arraytypemap[(int)(idprop->subtype)]; + r_prop_rna_or_id->rnaprop = arraytypemap[(int)(idprop->subtype)]; + r_prop_rna_or_id->is_array = true; + r_prop_rna_or_id->array_len = idprop_evaluated != NULL ? (uint)idprop_evaluated->len : 0; } else { - *prop = typemap[(int)(idprop->type)]; + r_prop_rna_or_id->rnaprop = typemap[(int)(idprop->type)]; } - - return idprop; } } @@ -605,14 +636,26 @@ static void *rna_idproperty_check_ex(PropertyRNA **prop, * or NULL (in case IDProp could not be found, or prop is a real RNA property). */ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) { - return rna_idproperty_check_ex(prop, ptr, false); + PropertyRNAOrID prop_rna_or_id; + + rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id); + + *prop = prop_rna_or_id.rnaprop; + return prop_rna_or_id.idprop; } /* This function always return the valid, real data pointer, be it a regular RNA property one, * or an IDProperty one. */ PropertyRNA *rna_ensure_property_realdata(PropertyRNA **prop, PointerRNA *ptr) { - return rna_idproperty_check_ex(prop, ptr, true); + PropertyRNAOrID prop_rna_or_id; + + rna_property_rna_or_id_get(*prop, ptr, &prop_rna_or_id); + + *prop = prop_rna_or_id.rnaprop; + return (prop_rna_or_id.is_idprop || prop_rna_or_id.idprop != NULL) ? + (PropertyRNA *)prop_rna_or_id.idprop : + prop_rna_or_id.rnaprop; } PropertyRNA *rna_ensure_property(PropertyRNA *prop) |