BKE_lib_remap: Refactor: Replace LinkNode by blender::Span.

This commit is contained in:
Bastien Montagne
2023-11-30 22:18:21 +01:00
parent 5d330ddb1f
commit dfe1a7d039
5 changed files with 41 additions and 55 deletions

View File

@@ -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<ID *> &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

View File

@@ -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<ID *> 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) {

View File

@@ -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<ID *> cleanup_ids = {};
for (ID *id = static_cast<ID *>(tagged_deleted_ids.first); id;
id = static_cast<ID *>(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);

View File

@@ -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<ID *> 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<ID *> 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 *> 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<ID *>(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<ID *>(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);

View File

@@ -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<ID *> &ids;
};
static void libblock_relink_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_data)
{
LibBlockRelinkMultipleUserData *data = static_cast<LibBlockRelinkMultipleUserData *>(user_data);
Main *bmain = data->bmain;
LinkNode *ids = data->ids;
const blender::Span<ID *> &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<ID *>(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<ID *> &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<ID *>(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<ID *>(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<ID *>(idv);
ID *old_id = static_cast<ID *>(old_idv);
ID *new_id = static_cast<ID *>(new_idv);
LinkNode ids{};
ids.next = nullptr;
ids.link = idv;
blender::Array<ID *> 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<ID *> 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);
}