[Bf-blender-cvs] [337e2c90293] master: RNA: refactor how we get 'ensured' RNA properties.

Bastien Montagne noreply at git.blender.org
Fri Jul 10 15:22:30 CEST 2020


Commit: 337e2c902930d8a8980505d66234bc46c95b051c
Author: Bastien Montagne
Date:   Fri Jul 10 15:19:40 2020 +0200
Branches: master
https://developer.blender.org/rB337e2c902930d8a8980505d66234bc46c95b051c

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.

===================================================================

M	source/blender/makesrna/intern/rna_access.c
M	source/blender/makesrna/intern/rna_access_internal.h
M	source/blender/makesrna/intern/rna_internal_types.h

===================================================================

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)
diff --git a/source/blender/makesrna/intern/rna_access_internal.h b/source/blender/makesrna/intern/rna_access_internal.h
index c7995746d08..ecc9386ca77 100644
--- a/source/blender/makesrna/intern/rna_access_internal.h
+++ b/source/blender/makesrna/intern/rna_access_internal.h
@@ -26,8 +26,12 @@
 #include "rna_internal_types.h"
 
 struct IDProperty;
+struct PropertyRNAOrID;
 
 PropertyRNA *rna_ensure_property(PropertyRNA *prop);
+void rna_property_rna_or_id_get(PropertyRNA *prop,
+                            PointerRNA *ptr,
+                            PropertyRNAOrID *r_prop_rna_or_id);
 
 void rna_idproperty_touch(struct IDProperty *idprop);
 struct IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 345d84fc5b1..6336be25ac3 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -41,6 +41,8 @@ struct Scene;
 struct StructRNA;
 struct bContext;
 
+typedef struct IDProperty IDProperty;
+
 /* store local properties here */
 #define RNA_IDP_UI "_RNA_UI"
 
@@ -155,6 +157,43 @@ typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *pr
 
 /* Handling override operations, and also comparison. */
 
+/** Structure storing all needed data to process all three kinds of RNA properties. */
+typedef struct PropertyRNAOrID {
+  PointerRNA ptr;
+
+  /** The PropertyRNA passed as parameter, used to generate that structure's content:
+   * - Static RNA: The RNA property (same as `rnaprop`), never NULL.
+   * - Runtime RNA: The RNA property (same as `rnaprop`), never NULL.
+   * - IDProperty: The IDProperty, never NULL.
+   */
+  PropertyRNA *rawprop;
+  /** The real RNA property of this property, never NULL:
+   * - Static RNA: The rna property, also gives direct access to the data (from any matching
+   *               PointerRNA).
+   * - Runtime RNA: The rna property, does not directly gives access to the data.
+   * - IDProperty: The generic PropertyRNA matching its type.
+   */
+  PropertyRNA *rnaprop;
+  /** The IDProperty storing the data of this property, may be NULL:
+   * - Static RNA: Always NULL.
+   * - Runtime RNA: The IDProperty storing the data of that property, may be NULL if never set yet.
+   * - IDProperty: The IDProperty, never NULL.
+   */
+  IDProperty *idprop;
+  /** The name of the property. */
+  const char *identifier;
+
+  /** Whether this property is a 'pure' IDProperty or not. */
+  bool is_idprop;
+  /** For runtime RNA properties, whether it is set, defined, or not.
+   * WARNING: This DOES take into account the `IDP_FLAG_GHOST` flag, i.e. it matches result of
+   *          `RNA_property_is_set`. */
+  bool is_set;
+
+  bool is_array;
+  uint array_len;
+} PropertyRNAOrID;
+
 /**
  * If \a override is NULL, merely do comparison between prop_a from ptr_a and prop_b from ptr_b,
  * following comparison mode given.



More information about the Bf-blender-cvs mailing list