From dfe1a7d039caa8ef5e4e228252f2b5a47a1f3f08 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 30 Nov 2023 22:18:21 +0100 Subject: [PATCH] BKE_lib_remap: Refactor: Replace `LinkNode` by `blender::Span`. --- source/blender/blenkernel/BKE_lib_remap.hh | 9 +++-- source/blender/blenkernel/intern/lib_id.cc | 14 +++----- .../blenkernel/intern/lib_id_delete.cc | 8 ++--- .../blender/blenkernel/intern/lib_override.cc | 31 ++++++++--------- source/blender/blenkernel/intern/lib_remap.cc | 34 +++++++------------ 5 files changed, 41 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/BKE_lib_remap.hh b/source/blender/blenkernel/BKE_lib_remap.hh index 375e467ceca..a62254b4958 100644 --- a/source/blender/blenkernel/BKE_lib_remap.hh +++ b/source/blender/blenkernel/BKE_lib_remap.hh @@ -21,11 +21,11 @@ */ #include "BLI_compiler_attrs.h" +#include "BLI_span.hh" #include "BLI_utildefines.h" struct ID; struct IDRemapper; -struct LinkNode; struct Main; /* BKE_libblock_free, delete are declared in BKE_lib_id.h for convenience. */ @@ -168,8 +168,11 @@ void BKE_libblock_relink_ex(Main *bmain, void *idv, void *old_idv, void *new_idv * Same as #BKE_libblock_relink_ex, but applies all rules defined in \a id_remapper to \a ids (or * does cleanup if `ID_REMAP_TYPE_CLEANUP` is specified as \a remap_type). */ -void BKE_libblock_relink_multiple( - Main *bmain, LinkNode *ids, eIDRemapType remap_type, IDRemapper *id_remapper, int remap_flags); +void BKE_libblock_relink_multiple(Main *bmain, + const blender::Span &ids, + eIDRemapType remap_type, + IDRemapper *id_remapper, + int remap_flags); /** * Remaps ID usages of given ID to their `id->newid` pointer if not None, and proceeds recursively diff --git a/source/blender/blenkernel/intern/lib_id.cc b/source/blender/blenkernel/intern/lib_id.cc index 529eeb68f8f..ba1520427b0 100644 --- a/source/blender/blenkernel/intern/lib_id.cc +++ b/source/blender/blenkernel/intern/lib_id.cc @@ -31,6 +31,7 @@ #include "BLI_utildefines.h" #include "BLI_alloca.h" +#include "BLI_array.hh" #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_linklist.h" @@ -859,15 +860,10 @@ static void id_swap(Main *bmain, /* Finalize remapping of internal references to self broken by swapping, if requested. */ if (do_self_remap) { - LinkNode ids{}; - ids.next = nullptr; - ids.link = id_a; - - BKE_libblock_relink_multiple( - bmain, &ids, ID_REMAP_TYPE_REMAP, remapper_id_a, self_remap_flags); - ids.link = id_b; - BKE_libblock_relink_multiple( - bmain, &ids, ID_REMAP_TYPE_REMAP, remapper_id_b, self_remap_flags); + blender::Array ids{id_a}; + BKE_libblock_relink_multiple(bmain, ids, ID_REMAP_TYPE_REMAP, remapper_id_a, self_remap_flags); + ids[0] = id_b; + BKE_libblock_relink_multiple(bmain, ids, ID_REMAP_TYPE_REMAP, remapper_id_b, self_remap_flags); } if (input_remapper_id_a == nullptr && remapper_id_a != nullptr) { diff --git a/source/blender/blenkernel/intern/lib_id_delete.cc b/source/blender/blenkernel/intern/lib_id_delete.cc index c707993095b..24376c7b3ed 100644 --- a/source/blender/blenkernel/intern/lib_id_delete.cc +++ b/source/blender/blenkernel/intern/lib_id_delete.cc @@ -20,6 +20,7 @@ #include "BLI_linklist.h" #include "BLI_listbase.h" +#include "BLI_vector.hh" #include "BKE_anim_data.h" #include "BKE_asset.hh" @@ -302,10 +303,10 @@ static size_t id_delete(Main *bmain, } /* Since we removed IDs from Main, their own other IDs usages need to be removed 'manually'. */ - LinkNode *cleanup_ids = nullptr; + blender::Vector cleanup_ids = {}; for (ID *id = static_cast(tagged_deleted_ids.first); id; id = static_cast(id->next)) { - BLI_linklist_prepend(&cleanup_ids, id); + cleanup_ids.append(id); } BKE_libblock_relink_multiple(bmain, cleanup_ids, @@ -313,9 +314,8 @@ static size_t id_delete(Main *bmain, id_remapper, ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS | ID_REMAP_SKIP_USER_CLEAR); - + cleanup_ids.clear(); BKE_id_remapper_free(id_remapper); - BLI_linklist_free(cleanup_ids, nullptr); BKE_layer_collection_resync_allow(); BKE_main_collection_sync_remap(bmain); diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 1a099fc0de0..cca962f27c1 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -54,6 +54,7 @@ #include "BLI_string.h" #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "PIL_time.h" @@ -643,7 +644,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, } BLI_assert(id_hierarchy_root != nullptr); - LinkNode *relinked_ids = nullptr; + blender::Vector relinked_ids; IDRemapper *id_remapper = BKE_id_remapper_create(); /* Still checking the whole Main, that way we can tag other local IDs as needing to be * remapped to use newly created overriding IDs, if needed. */ @@ -677,7 +678,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, (!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id) || owner_id->override_library->hierarchy_root == id_hierarchy_root)) { - BLI_linklist_prepend(&relinked_ids, other_id); + relinked_ids.append(other_id); } if (ID_IS_OVERRIDE_LIBRARY_REAL(other_id) && @@ -718,7 +719,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, ID_REMAP_SKIP_OVERRIDE_LIBRARY | ID_REMAP_FORCE_USER_REFCOUNT); BKE_id_remapper_free(id_remapper); - BLI_linklist_free(relinked_ids, nullptr); + relinked_ids.clear(); } else { /* We need to cleanup potentially already created data. */ @@ -1837,7 +1838,7 @@ static void lib_override_library_remap(Main *bmain, { ID *id; IDRemapper *remapper = BKE_id_remapper_create(); - LinkNode *nomain_ids = nullptr; + blender::Vector nomain_ids; FOREACH_MAIN_ID_BEGIN (bmain, id) { if (id->tag & LIB_TAG_DOIT && id->newid != nullptr && id->lib == id_root_reference->lib) { @@ -1861,7 +1862,7 @@ static void lib_override_library_remap(Main *bmain, continue; } - BLI_linklist_prepend(&nomain_ids, id_override_old_iter); + nomain_ids.append(id_override_old_iter); } /* Remap all IDs to use the new override. */ @@ -1872,7 +1873,6 @@ static void lib_override_library_remap(Main *bmain, remapper, ID_REMAP_FORCE_USER_REFCOUNT | ID_REMAP_FORCE_NEVER_NULL_USAGE); BKE_id_remapper_free(remapper); - BLI_linklist_free(nomain_ids, nullptr); } /** @@ -2280,7 +2280,7 @@ static bool lib_override_library_resync(Main *bmain, BKE_main_collection_sync(bmain); - LinkNode *id_override_old_list = nullptr; + blender::Vector id_override_old_vector; /* We need to apply override rules in a separate loop, after all ID pointers have been properly * remapped, and all new local override IDs have gotten their proper original names, otherwise @@ -2398,7 +2398,7 @@ static bool lib_override_library_resync(Main *bmain, } } - BLI_linklist_prepend(&id_override_old_list, id_override_old); + id_override_old_vector.append(id_override_old); } FOREACH_MAIN_ID_END; @@ -2407,17 +2407,15 @@ static bool lib_override_library_resync(Main *bmain, * This is necessary in case said old ID is not in Main anymore. */ IDRemapper *id_remapper = BKE_id_remapper_create(); BKE_libblock_relink_multiple(bmain, - id_override_old_list, + id_override_old_vector, ID_REMAP_TYPE_CLEANUP, id_remapper, ID_REMAP_FORCE_USER_REFCOUNT | ID_REMAP_FORCE_NEVER_NULL_USAGE); - for (LinkNode *ln_iter = id_override_old_list; ln_iter != nullptr; ln_iter = ln_iter->next) { - ID *id_override_old = static_cast(ln_iter->link); + for (ID *id_override_old : id_override_old_vector) { id_override_old->tag |= LIB_TAG_NO_USER_REFCOUNT; } + id_override_old_vector.clear(); BKE_id_remapper_free(id_remapper); - BLI_linklist_free(id_override_old_list, nullptr); - id_override_old_list = nullptr; /* Delete old override IDs. * Note that we have to use tagged group deletion here, since ID deletion also uses @@ -2442,7 +2440,7 @@ static bool lib_override_library_resync(Main *bmain, } else { /* Defer tagging. */ - BLI_linklist_prepend(&id_override_old_list, id_override_old); + id_override_old_vector.append(id_override_old); } } } @@ -2507,11 +2505,10 @@ static bool lib_override_library_resync(Main *bmain, FOREACH_MAIN_ID_END; /* Finalize tagging old liboverrides for deletion. */ - for (LinkNode *ln_iter = id_override_old_list; ln_iter != nullptr; ln_iter = ln_iter->next) { - ID *id_override_old = static_cast(ln_iter->link); + for (ID *id_override_old : id_override_old_vector) { id_override_old->tag |= LIB_TAG_DOIT; } - BLI_linklist_free(id_override_old_list, nullptr); + id_override_old_vector.clear(); /* Cleanup, many pointers in this GHash are already invalid now. */ BLI_ghash_free(linkedref_to_old_override, nullptr, nullptr); diff --git a/source/blender/blenkernel/intern/lib_remap.cc b/source/blender/blenkernel/intern/lib_remap.cc index 2134687adea..1aa5031a369 100644 --- a/source/blender/blenkernel/intern/lib_remap.cc +++ b/source/blender/blenkernel/intern/lib_remap.cc @@ -10,6 +10,7 @@ #include "CLG_log.h" +#include "BLI_array.hh" #include "BLI_linklist.h" #include "BLI_utildefines.h" @@ -733,23 +734,21 @@ void BKE_libblock_unlink(Main *bmain, struct LibBlockRelinkMultipleUserData { Main *bmain; - LinkNode *ids; + const blender::Span &ids; }; static void libblock_relink_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_data) { LibBlockRelinkMultipleUserData *data = static_cast(user_data); Main *bmain = data->bmain; - LinkNode *ids = data->ids; + const blender::Span &ids = data->ids; BLI_assert(old_id != nullptr); BLI_assert((new_id == nullptr) || GS(old_id->name) == GS(new_id->name)); BLI_assert(old_id != new_id); bool is_object_update_processed = false; - for (LinkNode *ln_iter = ids; ln_iter != nullptr; ln_iter = ln_iter->next) { - ID *id_iter = static_cast(ln_iter->link); - + for (ID *id_iter : ids) { /* Some after-process updates. * This is a bit ugly, but cannot see a way to avoid it. * Maybe we should do a per-ID callback for this instead? @@ -793,15 +792,14 @@ static void libblock_relink_foreach_idpair_cb(ID *old_id, ID *new_id, void *user } void BKE_libblock_relink_multiple(Main *bmain, - LinkNode *ids, + const blender::Span &ids, const eIDRemapType remap_type, IDRemapper *id_remapper, const int remap_flags) { BLI_assert(remap_type == ID_REMAP_TYPE_REMAP || BKE_id_remapper_is_empty(id_remapper)); - for (LinkNode *ln_iter = ids; ln_iter != nullptr; ln_iter = ln_iter->next) { - ID *id_iter = static_cast(ln_iter->link); + for (ID *id_iter : ids) { libblock_remap_data(bmain, id_iter, remap_type, id_remapper, remap_flags); } @@ -811,18 +809,14 @@ void BKE_libblock_relink_multiple(Main *bmain, switch (remap_type) { case ID_REMAP_TYPE_REMAP: { - LibBlockRelinkMultipleUserData user_data = {nullptr}; - user_data.bmain = bmain; - user_data.ids = ids; + LibBlockRelinkMultipleUserData user_data = {bmain, ids}; BKE_id_remapper_iter(id_remapper, libblock_relink_foreach_idpair_cb, &user_data); break; } case ID_REMAP_TYPE_CLEANUP: { bool is_object_update_processed = false; - for (LinkNode *ln_iter = ids; ln_iter != nullptr; ln_iter = ln_iter->next) { - ID *id_iter = static_cast(ln_iter->link); - + for (ID *id_iter : ids) { switch (GS(id_iter->name)) { case ID_SCE: case ID_GR: { @@ -868,9 +862,7 @@ void BKE_libblock_relink_ex( ID *id = static_cast(idv); ID *old_id = static_cast(old_idv); ID *new_id = static_cast(new_idv); - LinkNode ids{}; - ids.next = nullptr; - ids.link = idv; + blender::Array ids = {id}; /* No need to lock here, we are only affecting given ID, not bmain database. */ IDRemapper *id_remapper = BKE_id_remapper_create(); @@ -888,13 +880,13 @@ void BKE_libblock_relink_ex( remap_type = ID_REMAP_TYPE_CLEANUP; } - BKE_libblock_relink_multiple(bmain, &ids, remap_type, id_remapper, remap_flags); + BKE_libblock_relink_multiple(bmain, ids, remap_type, id_remapper, remap_flags); BKE_id_remapper_free(id_remapper); } struct RelinkToNewIDData { - LinkNode *ids; + blender::Vector ids; IDRemapper *id_remapper; }; @@ -936,7 +928,7 @@ static void libblock_relink_to_newid_prepare_data(Main *bmain, } id->tag &= ~LIB_TAG_NEW; - BLI_linklist_prepend(&relink_data->ids, id); + relink_data->ids.append(id); BKE_library_foreach_ID_link(bmain, id, id_relink_to_newid_looper, relink_data, 0); } @@ -949,7 +941,6 @@ void BKE_libblock_relink_to_newid(Main *bmain, ID *id, const int remap_flag) BLI_assert(bmain->relations == nullptr); RelinkToNewIDData relink_data{}; - relink_data.ids = nullptr; relink_data.id_remapper = BKE_id_remapper_create(); libblock_relink_to_newid_prepare_data(bmain, id, &relink_data); @@ -960,5 +951,4 @@ void BKE_libblock_relink_to_newid(Main *bmain, ID *id, const int remap_flag) bmain, relink_data.ids, ID_REMAP_TYPE_REMAP, relink_data.id_remapper, remap_flag_final); BKE_id_remapper_free(relink_data.id_remapper); - BLI_linklist_free(relink_data.ids, nullptr); }