Fix T73164: Undo does not always properly clear no-more-used library data.

Solution is actually very simple, and even makes existing code simpler:
just write all lib IDs when storing and undo step. That way we do not
have to guess which indirectly used library should be kept or not after
an undo step reading.
This commit is contained in:
Bastien Montagne 2020-05-25 17:39:16 +02:00
parent 6d4dc22e17
commit 396bf6ca78
Notes: blender-bot 2023-02-14 10:21:15 +01:00
Referenced by issue #73164, Undo does not always properly clear no-more-used library data
2 changed files with 5 additions and 35 deletions

View File

@ -428,41 +428,6 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain,
* but oldmain itself shall *never* be 'transferred' to new mainlist! */
BLI_assert(old_mainlist.first == oldmain);
if (bfd && old_mainlist.first != old_mainlist.last) {
/* Even though directly used libs have been already moved to new main,
* indirect ones have not.
* This is a bit annoying, but we have no choice but to keep them all for now -
* means some now unused data may remain in memory, but think we'll have to live with it. */
Main *libmain, *libmain_next;
Main *newmain = bfd->main;
ListBase new_mainlist = {newmain, newmain};
for (libmain = oldmain->next; libmain; libmain = libmain_next) {
libmain_next = libmain->next;
/* Note that LIB_INDIRECT does not work with libraries themselves, so we use non-NULL
* parent to detect indirect-linked ones. */
if (libmain->curlib && (libmain->curlib->parent != NULL)) {
BLI_remlink(&old_mainlist, libmain);
BLI_addtail(&new_mainlist, libmain);
}
else {
#ifdef PRINT_DEBUG
printf("Dropped Main for lib: %s\n", libmain->curlib->id.name);
#endif
}
}
/* In any case, we need to move all lib data-blocks themselves - those are
* 'first level data', getting rid of them would imply updating spaces & co
* to prevent invalid pointers access. */
BLI_movelisttolist(&newmain->libraries, &oldmain->libraries);
blo_join_main(&new_mainlist);
}
#if 0
printf("Remaining mains/libs in oldmain: %d\n", BLI_listbase_count(&fd->old_mainlist) - 1);
#endif
/* That way, libs (aka mains) we did not reuse in new undone/redone state
* will be cleared together with oldmain... */
blo_join_main(&old_mainlist);

View File

@ -3917,6 +3917,11 @@ static void write_libraries(WriteData *wd, Main *main)
if (main->curlib && main->curlib->packedfile) {
found_one = true;
}
else if (wd->use_memfile) {
/* When writing undo step we always write all existing libraries, makes reading undo step
* much easier when dealing with purely indirectly used libraries. */
found_one = true;
}
else {
found_one = false;
while (!found_one && tot--) {