[Bf-blender-cvs] [9f090bac5c7] blender-v2.83-release: IDProperties: add a foreach looper and use it in libquery code.

Bastien Montagne noreply at git.blender.org
Tue Apr 28 15:29:25 CEST 2020


Commit: 9f090bac5c7455ab22cd22cc3f6ea94b54d6de33
Author: Bastien Montagne
Date:   Sat Apr 25 20:58:55 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rB9f090bac5c7455ab22cd22cc3f6ea94b54d6de33

IDProperties: add a foreach looper and use it in libquery code.

Note: part of fix for T75279.

Differential Revision: https://developer.blender.org/D7550

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

M	source/blender/blenkernel/BKE_idprop.h
M	source/blender/blenkernel/intern/idprop.c
M	source/blender/blenkernel/intern/lib_query.c
M	source/blender/makesdna/DNA_ID.h

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

diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 2b02895043f..1272127daa0 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -179,6 +179,17 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference);
 #  define IDP_Id(prop) ((ID *)(prop)->data.pointer)
 #endif
 
+/**
+ * Call a callback for each idproperty in the hierarchy under given root one (included).
+ *
+ */
+typedef void (*IDPForeachPropertyCallback)(IDProperty *id_property, void *user_data);
+
+void IDP_foreach_property(struct IDProperty *id_property_root,
+                          const int type_filter,
+                          IDPForeachPropertyCallback callback,
+                          void *user_data);
+
 /* Format IDProperty as strings */
 char *IDP_reprN(const struct IDProperty *prop, uint *r_len);
 void IDP_repr_fn(const IDProperty *prop,
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5530a126ffc..669539ca574 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -1130,4 +1130,45 @@ void IDP_Reset(IDProperty *prop, const IDProperty *reference)
   }
 }
 
+/**
+ * Loop through all ID properties in hierarchy of given \a id_property_root included.
+ *
+ * \note Container types (groups and arrays) are processed after applying the callback on them.
+ *
+ * \param type_filter: If not 0, only apply callback on properties of matching types, see
+ * IDP_TYPE_FILTER_ enum in DNA_ID.h.
+ */
+void IDP_foreach_property(IDProperty *id_property_root,
+                          const int type_filter,
+                          IDPForeachPropertyCallback callback,
+                          void *user_data)
+{
+  if (!id_property_root) {
+    return;
+  }
+
+  if (type_filter == 0 || (1 << id_property_root->type) & type_filter) {
+    callback(id_property_root, user_data);
+  }
+
+  /* Recursive call into container types of ID properties. */
+  switch (id_property_root->type) {
+    case IDP_GROUP: {
+      LISTBASE_FOREACH (IDProperty *, loop, &id_property_root->data.group) {
+        IDP_foreach_property(loop, type_filter, callback, user_data);
+      }
+      break;
+    }
+    case IDP_IDPARRAY: {
+      IDProperty *loop = IDP_Array(id_property_root);
+      for (int i = 0; i < id_property_root->len; i++) {
+        IDP_foreach_property(&loop[i], type_filter, callback, user_data);
+      }
+      break;
+    }
+    default:
+      break; /* Nothing to do here with other types of IDProperties... */
+  }
+}
+
 /** \} */
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 4ffdcf14fa7..c93aade7cfa 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -172,34 +172,12 @@ static void library_foreach_ID_link(Main *bmain,
                                     int flag,
                                     LibraryForeachIDData *inherit_data);
 
-static void library_foreach_idproperty_ID_link(LibraryForeachIDData *data,
-                                               IDProperty *prop,
-                                               int flag)
+static void library_foreach_idpropertiesForeachIDLink(IDProperty *id_prop, void *user_data)
 {
-  if (!prop) {
-    return;
-  }
+  BLI_assert(id_prop->type == IDP_ID);
 
-  switch (prop->type) {
-    case IDP_GROUP: {
-      LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
-        library_foreach_idproperty_ID_link(data, loop, flag);
-      }
-      break;
-    }
-    case IDP_IDPARRAY: {
-      IDProperty *loop = IDP_Array(prop);
-      for (int i = 0; i < prop->len; i++) {
-        library_foreach_idproperty_ID_link(data, &loop[i], flag);
-      }
-      break;
-    }
-    case IDP_ID:
-      FOREACH_CALLBACK_INVOKE_ID(data, prop->data.pointer, flag);
-      break;
-    default:
-      break; /* Nothing to do here with other types of IDProperties... */
-  }
+  LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
+  FOREACH_CALLBACK_INVOKE_ID(data, id_prop->data.pointer, IDWALK_CB_USER);
 
   FOREACH_FINALIZE_VOID;
 }
@@ -336,7 +314,8 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
 
 static void library_foreach_bone(LibraryForeachIDData *data, Bone *bone)
 {
-  library_foreach_idproperty_ID_link(data, bone->prop, IDWALK_CB_USER);
+  IDP_foreach_property(
+      bone->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, data);
 
   LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
     library_foreach_bone(data, curbone);
@@ -642,7 +621,8 @@ static void library_foreach_ID_link(Main *bmain,
                          IDWALK_CB_USER | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE);
     }
 
-    library_foreach_idproperty_ID_link(&data, id->properties, IDWALK_CB_USER);
+    IDP_foreach_property(
+        id->properties, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
 
     AnimData *adt = BKE_animdata_from_id(id);
     if (adt) {
@@ -678,7 +658,8 @@ static void library_foreach_ID_link(Main *bmain,
             CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER);
             CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER);
             CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER);
-            library_foreach_idproperty_ID_link(&data, seq->prop, IDWALK_CB_USER);
+            IDP_foreach_property(
+                seq->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
             LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
               CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
             }
@@ -836,7 +817,8 @@ static void library_foreach_ID_link(Main *bmain,
 
           data.cb_flag |= proxy_cb_flag;
           for (pchan = object->pose->chanbase.first; pchan; pchan = pchan->next) {
-            library_foreach_idproperty_ID_link(&data, pchan->prop, IDWALK_CB_USER);
+            IDP_foreach_property(
+                pchan->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
             CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
             BKE_constraints_id_loop(
                 &pchan->constraints, library_foreach_constraintObjectLooper, &data);
@@ -1024,20 +1006,25 @@ static void library_foreach_ID_link(Main *bmain,
         for (node = ntree->nodes.first; node; node = node->next) {
           CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER);
 
-          library_foreach_idproperty_ID_link(&data, node->prop, IDWALK_CB_USER);
+          IDP_foreach_property(
+              node->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
           for (sock = node->inputs.first; sock; sock = sock->next) {
-            library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+            IDP_foreach_property(
+                sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
           }
           for (sock = node->outputs.first; sock; sock = sock->next) {
-            library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+            IDP_foreach_property(
+                sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
           }
         }
 
         for (sock = ntree->inputs.first; sock; sock = sock->next) {
-          library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+          IDP_foreach_property(
+              sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
         }
         for (sock = ntree->outputs.first; sock; sock = sock->next) {
-          library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+          IDP_foreach_property(
+              sock->prop, IDP_TYPE_FILTER_ID, library_foreach_idpropertiesForeachIDLink, &data);
         }
         break;
       }
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index d6d3628cc66..5230cb050f4 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -106,6 +106,18 @@ enum {
   IDP_NUMTYPES = 10,
 };
 
+/** Used by some IDP utils, keep values in sync with type enum above. */
+enum {
+  IDP_TYPE_FILTER_STRING = 1 << 0,
+  IDP_TYPE_FILTER_INT = 1 << 1,
+  IDP_TYPE_FILTER_FLOAT = 1 << 2,
+  IDP_TYPE_FILTER_ARRAY = 1 << 5,
+  IDP_TYPE_FILTER_GROUP = 1 << 6,
+  IDP_TYPE_FILTER_ID = 1 << 7,
+  IDP_TYPE_FILTER_DOUBLE = 1 << 8,
+  IDP_TYPE_FILTER_IDPARRAY = 1 << 9,
+};
+
 /*->subtype */
 
 /* IDP_STRING */



More information about the Bf-blender-cvs mailing list