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:
authorBastien Montagne <bastien@blender.org>2020-07-10 16:19:40 +0300
committerBastien Montagne <bastien@blender.org>2020-07-10 16:19:40 +0300
commit337e2c902930d8a8980505d66234bc46c95b051c (patch)
treed34a163fcdd1fc06dd85fdefcafa97f4a6abf89a /source/blender/makesrna/intern/rna_access.c
parent6c1157201a143574c005147367bb2fd4ab320e73 (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.c79
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)