Fix T97688: Deleting a scene with a scene strip causes the referenced scene to have zero users

Relinking code would weirdly enough allow clearing of extra/fake user
status on IDs used by affected ID, which would be utterly wrong.

Fairly unclear why this was working OK in reported case before rBa71a513def20,
could not spot any obvious reason just from reading code...

Also, in `libblock_remap_data_update_tags`, only transfer fake user
status if `new_id` is not NULL (otherwise that would have removed that
falg from `old_id`, without actually transferring it to anything).
This commit is contained in:
Bastien Montagne 2022-05-02 15:54:15 +02:00
parent 263f56ba49
commit 5188c14718
Notes: blender-bot 2023-02-14 07:17:43 +01:00
Referenced by commit 60772baebf, Fix T97709: Compositor: Scenes are being set to no users after doing a full copy.
Referenced by issue #98444, Regression: image.save_render() command changes color profile and file type when saving.
Referenced by issue #98374, Assert fails in some tests
Referenced by issue #97688, Deleting a scene with a scene strip causes the referenced scene to have zero users
2 changed files with 9 additions and 4 deletions

View File

@ -120,7 +120,7 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
Key *key = ((flag & LIB_ID_FREE_NO_MAIN) == 0) ? BKE_key_from_id(id) : NULL;
if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
BKE_libblock_relink_ex(bmain, id, NULL, NULL, 0);
BKE_libblock_relink_ex(bmain, id, NULL, NULL, ID_REMAP_SKIP_USER_CLEAR);
}
if ((flag & LIB_ID_FREE_NO_MAIN) == 0 && key != NULL) {
@ -264,7 +264,12 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS));
/* Since we removed ID from Main,
* we also need to unlink its own other IDs usages ourself. */
BKE_libblock_relink_ex(bmain, id, NULL, NULL, ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS);
BKE_libblock_relink_ex(
bmain,
id,
NULL,
NULL,
(ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS | ID_REMAP_SKIP_USER_CLEAR));
}
}

View File

@ -409,7 +409,7 @@ static void libblock_remap_data_update_tags(ID *old_id, ID *new_id, void *user_d
/* XXX We may not want to always 'transfer' fake-user from old to new id...
* Think for now it's desired behavior though,
* we can always add an option (flag) to control this later if needed. */
if (old_id && (old_id->flag & LIB_FAKEUSER)) {
if (old_id != NULL && (old_id->flag & LIB_FAKEUSER) && new_id != NULL) {
id_fake_user_clear(old_id);
id_fake_user_set(new_id);
}
@ -417,7 +417,7 @@ static void libblock_remap_data_update_tags(ID *old_id, ID *new_id, void *user_d
id_us_clear_real(old_id);
}
if (new_id && (new_id->tag & LIB_TAG_INDIRECT) &&
if (new_id != NULL && (new_id->tag & LIB_TAG_INDIRECT) &&
(new_id->runtime.remap.status & ID_REMAP_IS_LINKED_DIRECT)) {
new_id->tag &= ~LIB_TAG_INDIRECT;
new_id->flag &= ~LIB_INDIRECT_WEAK_LINK;