Cleanup: replace Main ID's foreach functions by macros.
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 14 Feb 2019 15:24:49 +0000 (16:24 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 14 Feb 2019 15:26:32 +0000 (16:26 +0100)
Am really no a big fan of using macros for that kind of things, but
meh... C solution to do that with functions (using callbacks) is
even worse. :(

source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/intern/library_query.c
source/blender/blenkernel/intern/main.c
source/blender/editors/space_outliner/outliner_edit.c

index a96c1399979a1aaa44c8315ed705ad278826597e..08b6d47877e6113602c6bba3a217d620ed28123a 100644 (file)
@@ -140,14 +140,39 @@ void BKE_main_relations_free(struct Main *bmain);
 struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset);
 
 /* *** Generic utils to loop over whole Main database. *** */
-/** \return false to stop iteration, true to keep going. */
-typedef bool (*MainForeachIDCallback) (struct Main *bmain, struct ID *id, void *user_data);
-bool BKE_main_listbase_foreach_id(
-        struct Main *bmain, struct ListBase *lb,
-        MainForeachIDCallback callback, void *user_data);
-bool BKE_main_foreach_id(
-        struct Main *bmain, const bool reverse_type_order,
-        MainForeachIDCallback callback, void *user_data);
+
+#define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id)                          \
+       for (_id = _lb->first; _id != NULL; _id = _id->next) {                \
+
+#define FOREACH_MAIN_LISTBASE_ID_END                                      \
+       } ((void)0)
+
+
+#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)                                \
+       {                                                                     \
+               ListBase *_lbarray[MAX_LIBARRAY];                                 \
+               int i = set_listbasepointers(_bmain, _lbarray);                   \
+               while (i--) {                                                     \
+                       FOREACH_MAIN_LISTBASE_ID_BEGIN(_lbarray[i], _id)              \
+
+#define FOREACH_MAIN_ID_END                                               \
+                       FOREACH_MAIN_LISTBASE_ID_END;                                 \
+               }                                                                 \
+       } ((void)0)
+
+/** \param _do_break A boolean, to allow breaking iteration (only used to break by type,
+ *                   you must also use an explicit `break;` operation if you want to
+ *                   immediately break from inner by-ID loop).
+ */
+#define FOREACH_MAIN_ID_BREAKABLE_BEGIN(_bmain, _id, _do_break)           \
+       {                                                                     \
+               ListBase *_lbarray[MAX_LIBARRAY];                                 \
+               int i = set_listbasepointers(_bmain, _lbarray);                   \
+               while (i-- && !_do_break) {                                       \
+                       FOREACH_MAIN_LISTBASE_ID_BEGIN(_lbarray[i], _id)              \
+
+#define FOREACH_MAIN_ID_BREAKABLE_END FOREACH_MAIN_ID_END
+
 
 struct BlendThumbnail *BKE_main_thumbnail_from_imbuf(struct Main *bmain, struct ImBuf *img);
 struct ImBuf *BKE_main_thumbnail_to_imbuf(struct Main *bmain, struct BlendThumbnail *data);
index cfda7ab2682a4ff3e31b475efb140306c6256fef..29e0ee0715d85f326ce816fe3f79260fa512d083 100644 (file)
@@ -1328,27 +1328,6 @@ static int foreach_libblock_used_linked_data_tag_clear_cb(
        return IDWALK_RET_NOP;
 }
 
-static bool unused_linked_data_tag_init_cb(Main *UNUSED(bmain), ID *id, void *UNUSED(user_data))
-{
-       if (id->lib && (id->tag & LIB_TAG_INDIRECT) != 0) {
-               id->tag |= LIB_TAG_DOIT;
-       }
-       else {
-               id->tag &= ~LIB_TAG_DOIT;
-       }
-       return true;
-}
-
-static bool unused_linked_data_check_cb(Main *bmain, ID *id, void *user_data)
-{
-       if ((id->tag & LIB_TAG_DOIT) == 0) {
-               BKE_library_foreach_ID_link(
-                           bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, user_data, IDWALK_READONLY);
-       }
-       /* Else it is an unused ID (so far), no need to check it further. */
-       return true;
-}
-
 /**
  * Detect orphaned linked data blocks (i.e. linked data not used (directly or indirectly) in any way by any local data),
  * including complex cases like 'linked archipelagoes', i.e. linked datablocks that use each other in loops,
@@ -1359,13 +1338,35 @@ static bool unused_linked_data_check_cb(Main *bmain, ID *id, void *user_data)
  */
 void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
 {
+       ID *id;
+
        if (do_init_tag) {
-               BKE_main_foreach_id(bmain, true, unused_linked_data_tag_init_cb, NULL);
+               FOREACH_MAIN_ID_BEGIN(bmain, id)
+               {
+                       if (id->lib && (id->tag & LIB_TAG_INDIRECT) != 0) {
+                               id->tag |= LIB_TAG_DOIT;
+                       }
+                       else {
+                               id->tag &= ~LIB_TAG_DOIT;
+                       }
+               }
+               FOREACH_MAIN_ID_END;
        }
 
        for (bool do_loop = true; do_loop; ) {
+               bool do_break = false;
                do_loop = false;
-               BKE_main_foreach_id(bmain, true, unused_linked_data_check_cb, &do_loop);
+               FOREACH_MAIN_ID_BREAKABLE_BEGIN(bmain, id, do_break)
+               {
+                       if ((id->tag & LIB_TAG_DOIT) == 0) {
+                               BKE_library_foreach_ID_link(
+                                           bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
+                       }
+                       /* Else it is an unused ID (so far), no need to check it further. */
+                       do_break = true;
+                       break;
+               }
+               FOREACH_MAIN_ID_BREAKABLE_END;
        }
 }
 
index 11150f827e225cf4f6daa864e0e09d542fb77d8d..a4500e6616d4774e8916c606288e8514dbbb3f1d 100644 (file)
@@ -173,12 +173,6 @@ static int main_relations_create_idlink_cb(void *user_data, ID *id_self, ID **id
        return IDWALK_RET_NOP;
 }
 
-static bool main_relations_create_id_cb(Main *bmain, ID *id, void *UNUSED(user_data))
-{
-       BKE_library_foreach_ID_link(NULL, id, main_relations_create_idlink_cb, bmain->relations, IDWALK_READONLY);
-       return true;
-}
-
 /** Generate the mappings between used IDs and their users, and vice-versa. */
 void BKE_main_relations_create(Main *bmain)
 {
@@ -191,7 +185,12 @@ void BKE_main_relations_create(Main *bmain)
        bmain->relations->id_user_to_used = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
        bmain->relations->entry_pool = BLI_mempool_create(sizeof(MainIDRelationsEntry), 128, 128, BLI_MEMPOOL_NOP);
 
-       BKE_main_foreach_id(bmain, false, main_relations_create_id_cb, NULL);
+       ID *id;
+       FOREACH_MAIN_ID_BEGIN(bmain, id)
+       {
+               BKE_library_foreach_ID_link(NULL, id, main_relations_create_idlink_cb, bmain->relations, IDWALK_READONLY);
+       }
+       FOREACH_MAIN_ID_END;
 }
 
 void BKE_main_relations_free(Main *bmain)
@@ -209,13 +208,6 @@ void BKE_main_relations_free(Main *bmain)
        }
 }
 
-static bool main_gset_create(Main *UNUSED(bmain), ID *id, void *user_data)
-{
-       GSet *gset = user_data;
-       BLI_gset_add(gset, id);
-       return true;
-}
-
 /**
  * Create a GSet storing all IDs present in given \a bmain, by their pointers.
  *
@@ -226,57 +218,14 @@ GSet *BKE_main_gset_create(Main *bmain, GSet *gset)
        if (gset == NULL) {
                gset = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
        }
-       BKE_main_foreach_id(bmain, false, main_gset_create, gset);
-       return gset;
-}
-
-/**
- * Call given callback over every IDs of given \a lb listbase (assumed to be part of given \a bmain).
- *
- * \return false if the iteration was iterrupted by the callback.
- *
- * \warning \a callback may affect the ID, but DO NOT change the listbase or Main database (add/remove/reorder its IDs).
- */
-bool BKE_main_listbase_foreach_id(
-        Main *bmain, ListBase *lb,
-        MainForeachIDCallback callback, void *user_data)
-{
-       bool keep_looping = true;
-       for (ID *id = lb->first; id; id = id->next) {
-               if (!(keep_looping = callback(bmain, id, user_data))) {
-                       return keep_looping;
-               }
-       }
-       return keep_looping;
-}
-
-/**
- * Call given callback over every IDs of given \a bmain Main database.
- *
- * \param reverse_type_order: Allow to reverse order in which ID *types* are handled
- * (i.e. does not reverse the order in which IDs themselves are handled whithin a give listbase).
- * Note that in most cases, you want to set that parameter to true.
- * \return false if the iteration was iterrupted by the callback.
- *
- * \warning \a callback may affect the ID, but DO NOT change the Main database (add/remove/reorder its IDs).
- */
-bool BKE_main_foreach_id(
-        Main *bmain, const bool reverse_type_order,
-        MainForeachIDCallback callback, void *user_data)
-{
-       ListBase *lbarray[MAX_LIBARRAY];
-       const int nbr_types = set_listbasepointers(bmain, lbarray);
 
-       bool keep_looping = true;
-       for (int i = reverse_type_order ? nbr_types - 1 : 0;
-            reverse_type_order ? i >= 0 : i < nbr_types;
-            reverse_type_order ? i-- : i++)
+       ID *id;
+       FOREACH_MAIN_ID_BEGIN(bmain, id)
        {
-               if (!(keep_looping = BKE_main_listbase_foreach_id(bmain, lbarray[i], callback, user_data))) {
-                       return keep_looping;
-               }
+               BLI_gset_add(gset, id);
        }
-       return keep_looping;
+       FOREACH_MAIN_ID_END;
+       return gset;
 }
 
 /**
index 186f547fd955dfd031bb43ae4bd18b880506fe8e..ac0e00a38bdaa9348f965b81a38751d3053f1254 100644 (file)
@@ -1849,10 +1849,8 @@ static bool ed_operator_outliner_id_orphans_active(bContext *C)
 
 /* Purge Orphans Operator --------------------------------------- */
 
-static bool outliner_orphans_purge_tag_cb(Main *UNUSED(bmain), ID *id, void *user_data)
+static void outliner_orphans_purge_tag(ID *id, int *num_tagged)
 {
-       int *num_tagged = (int *)user_data;
-
        if (id->us == 0) {
                id->tag |= LIB_TAG_DOIT;
                num_tagged[INDEX_ID_NULL]++;
@@ -1861,7 +1859,6 @@ static bool outliner_orphans_purge_tag_cb(Main *UNUSED(bmain), ID *id, void *use
        else {
                id->tag &= ~LIB_TAG_DOIT;
        }
-       return true;
 }
 
 static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
@@ -1870,7 +1867,12 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
        int num_tagged[INDEX_ID_MAX] = {0};
 
        /* Tag all IDs having zero users. */
-       BKE_main_foreach_id(bmain, false, outliner_orphans_purge_tag_cb, num_tagged);
+       ID *id;
+       FOREACH_MAIN_ID_BEGIN(bmain, id)
+       {
+               outliner_orphans_purge_tag(id, num_tagged);
+       }
+       FOREACH_MAIN_ID_END;
        RNA_int_set(op->ptr, "num_deleted", num_tagged[INDEX_ID_NULL]);
 
        if (num_tagged[INDEX_ID_NULL] == 0) {
@@ -1912,7 +1914,12 @@ static int outliner_orphans_purge_exec(bContext *C, wmOperator *op)
 
        if ((num_tagged[INDEX_ID_NULL] = RNA_int_get(op->ptr, "num_deleted")) == 0) {
                /* Tag all IDs having zero users. */
-               BKE_main_foreach_id(bmain, false, outliner_orphans_purge_tag_cb, num_tagged);
+               ID *id;
+               FOREACH_MAIN_ID_BEGIN(bmain, id)
+               {
+                       outliner_orphans_purge_tag(id, num_tagged);
+               }
+               FOREACH_MAIN_ID_END;
 
                if (num_tagged[INDEX_ID_NULL] == 0) {
                        BKE_report(op->reports, RPT_INFO, "No orphanned data-blocks to purge");