diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-14 18:24:49 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-14 18:26:32 +0300 |
commit | fa7149893a6c9d61ba840475b6d96172b0d55a67 (patch) | |
tree | 015369a94910b8c53695eee9d4b310263c6cf12c /source | |
parent | caf89c3de16993a8153281ecf5919b40e2fff069 (diff) |
Cleanup: replace Main ID's foreach functions by macros.
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. :(
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_main.h | 41 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 47 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/main.c | 73 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_edit.c | 19 |
4 files changed, 81 insertions, 99 deletions
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index a96c1399979..08b6d47877e 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -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); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index cfda7ab2682..29e0ee0715d 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -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; } } diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c index 11150f827e2..a4500e6616d 100644 --- a/source/blender/blenkernel/intern/main.c +++ b/source/blender/blenkernel/intern/main.c @@ -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; } /** diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 186f547fd95..ac0e00a38bd 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -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"); |