BKE_lib_remap: Refactor: Replace LinkNode by blender::Span.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user