Commit: 3ad2d6caef7410aec67ebde416f03c9a06014e8a Author: Brecht Van Lommel Date: Wed Feb 27 19:25:21 2019 +0100 Branches: master https://developer.blender.org/rB3ad2d6caef7410aec67ebde416f03c9a06014e8a
Cleanup: better names and comments for library ID linking code. Differential Revision: https://developer.blender.org/D4415 =================================================================== M source/blender/blenkernel/intern/idcode.c M source/blender/blenloader/intern/readfile.c M source/blender/blenloader/intern/writefile.c M source/blender/makesdna/DNA_ID.h =================================================================== diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index d34dd2e70df..1c63f184bde 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -87,10 +87,10 @@ static IDType idtypes[] = { {ID_WS, "WorkSpace", "workspaces", BLT_I18NCONTEXT_ID_WORKSPACE, IDTYPE_FLAGS_ISLINKABLE}, /** Keep last, not an ID exactly, only include for completeness */ - {ID_ID, "ID", "ids", BLT_I18NCONTEXT_ID_ID, 0 }, /* plural is fake */ + {ID_LINK_PLACEHOLDER, "Link Placeholder", "link_placeholders", BLT_I18NCONTEXT_ID_ID, 0}, /* plural is fake */ }; -/* -1 for ID_ID */ +/* -1 for ID_LINK_PLACEHOLDER */ BLI_STATIC_ASSERT((ARRAY_SIZE(idtypes) - 1 == MAX_LIBARRAY), "Missing IDType"); static IDType *idtype_from_name(const char *str) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2472e900e80..9e4be469fb7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1754,19 +1754,19 @@ static void *newlibadr_real_us(FileData *fd, const void *lib, const void *adr) return id; } -static void change_idid_adr_fd(FileData *fd, const void *old, void *new) +static void change_link_placeholder_to_real_ID_pointer_fd(FileData *fd, const void *old, void *new) { for (int i = 0; i < fd->libmap->nentries; i++) { OldNew *entry = &fd->libmap->entries[i]; - if (old == entry->newp && entry->nr == ID_ID) { + if (old == entry->newp && entry->nr == ID_LINK_PLACEHOLDER) { entry->newp = new; if (new) entry->nr = GS( ((ID *)new)->name); } } } -static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, void *new) +static void change_link_placeholder_to_real_ID_pointer(ListBase *mainlist, FileData *basefd, void *old, void *new) { Main *mainptr; @@ -1779,7 +1779,7 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi fd = basefd; if (fd) { - change_idid_adr_fd(fd, old, new); + change_link_placeholder_to_real_ID_pointer_fd(fd, old, new); } } } @@ -8156,8 +8156,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main) TIP_("Library '%s', '%s' had multiple instances, save and reload!"), lib->name, lib->filepath); - change_idid_adr(fd->mainlist, fd, lib, newmain->curlib); -/* change_idid_adr_fd(fd, lib, newmain->curlib); */ + change_link_placeholder_to_real_ID_pointer(fd->mainlist, fd, lib, newmain->curlib); +/* change_link_placeholder_to_real_ID_pointer_fd(fd, lib, newmain->curlib); */ BLI_remlink(&main->library, lib); MEM_freeN(lib); @@ -8927,7 +8927,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta * This leads e.g. to desappearing objects in some undo/redo case, see T34446. * That means we have to carefully check whether current lib or libdata already exits in old main, if it does * we merely copy it over into new main area, otherwise we have to do a full read of that bhead... */ - if (fd->memfile && ELEM(bhead->code, ID_LI, ID_ID)) { + if (fd->memfile && ELEM(bhead->code, ID_LI, ID_LINK_PLACEHOLDER)) { const char *idname = blo_bhead_id_name(fd, bhead); DEBUG_PRINTF("Checking %s...\n", idname); @@ -8941,7 +8941,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta Main *oldmain = fd->old_mainlist->first; DEBUG_PRINTF("FOUND!\n"); /* In case of a library, we need to re-add its main to fd->mainlist, because if we have later - * a missing ID_ID, we need to get the correct lib it is linked to! + * a missing ID_LINK_PLACEHOLDER, we need to get the correct lib it is linked to! * Order is crucial, we cannot bulk-add it in BLO_read_from_memfile() like it used to be... */ BLI_remlink(fd->old_mainlist, libmain); BLI_remlink_safe(&oldmain->library, libmain->curlib); @@ -8965,7 +8965,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta oldnewmap_insert(fd->libmap, bhead->old, id, GS(id->name)); } - /* No need to do anything else for ID_ID, it's assumed already present in its lib's main... */ + /* No need to do anything else for ID_LINK_PLACEHOLDER, it's assumed already present in its lib's main... */ if (r_id) { *r_id = NULL; /* Just in case... */ } @@ -8983,7 +8983,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta /* do after read_struct, for dna reconstruct */ lb = which_libbase(main, idcode); if (lb) { - oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); /* for ID_ID check */ + oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); /* for ID_LINK_PLACEHOLDER check */ BLI_addtail(lb, id); } else { @@ -9007,7 +9007,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const int ta id->recalc = 0; /* this case cannot be direct_linked: it's just the ID part */ - if (bhead->code == ID_ID) { + if (bhead->code == ID_LINK_PLACEHOLDER) { /* That way, we know which datablock needs do_versions (required currently for linking). */ id->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_NEW; @@ -9516,14 +9516,17 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) bhead = NULL; break; - case ID_ID: - /* Always adds to the most recently loaded ID_LI block, see direct_link_library. - * This is part of the file format definition. */ + case ID_LINK_PLACEHOLDER: if (fd->skip_flags & BLO_READ_SKIP_DATA) { bhead = blo_bhead_next(fd, bhead); } else { - bhead = read_libblock(fd, mainlist.last, bhead, LIB_TAG_ID_ID | LIB_TAG_EXTERN, NULL); + /* Add link placeholder to the main of the library it belongs to. + * The library is the most recently loaded ID_LI block, according + * to the file format definition. So we can use the entry at the + * end of mainlist, added in direct_link_library. */ + Main *libmain = mainlist.last; + bhead = read_libblock(fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_EXTERN, NULL); } break; /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ @@ -9727,83 +9730,89 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead) static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) { - BHead *bhead; FileData *fd = fdhandle; - ID *id; - bhead = find_bhead(fd, old); - if (bhead) { - /* from another library? */ - if (bhead->code == ID_ID) { - BHead *bheadlib = find_previous_lib(fd, bhead); + BHead *bhead = find_bhead(fd, old); + if (bhead == NULL) { + return; + } - if (bheadlib) { - Library *lib = read_struct(fd, bheadlib, "Library"); - Main *ptr = blo_find_main(fd, lib->name, fd->relabase); + if (bhead->code == ID_LINK_PLACEHOLDER) { + /* Placeholder link to datablock in another library. */ + BHead *bheadlib = find_previous_lib(fd, bhead); + if (bheadlib == NULL) { + return; + } - if (ptr->curlib == NULL) { - const char *idname = blo_bhead_id_name(fd, bhead); + Library *lib = read_struct(fd, bheadlib, "Library"); + Main *libmain = blo_find_main(fd, lib->name, fd->relabase); - blo_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB: Data refers to main .blend file: '%s' from %s"), - idname, mainvar->curlib->filepath); - return; - } - else - id = is_yet_read(fd, ptr, bhead); + if (libmain->curlib == NULL) { + const char *idname = blo_bhead_id_name(fd, bhead); - if (id == NULL) { - read_libblock(fd, ptr, bhead, LIB_TAG_ID_ID | LIB_TAG_INDIRECT, NULL); - // commented because this can print way too much - // if (G.debug & G_DEBUG) printf("expand_doit: other lib %s\n", lib->name); + blo_reportf_wrap(fd->reports, RPT_WARNING, TIP_("LIB: Data refers to main .blend file: '%s' from %s"), + idname, mainvar->curlib->filepath); + return; + } - /* for outliner dependency only */ - ptr->curlib->parent = mainvar->curlib; - } - else { - /* The line below was commented by Ton (I assume), when Hos did the merge from the orange branch. rev 6568 - * This line is NEEDED, the case is that you have 3 blend files... - * user.blend, lib.blend and lib_indirect.blend - if user.blend already references a "tree" from - * lib_indirect.blend but lib.blend does too, linking in a Scene or Group from lib.blend can result in an - * empty without the dupli group referenced. Once you save and reload the group would appear. - Campbell */ - /* This crashes files, must look further into it */ - - /* Update: the issue is that in file reading, the oldnewmap is OK, but for existing data, it has to be - * inserted in the map to be found! */ - - /* Update: previously it was checking for id->tag & LIB_TAG_PRE_EXISTING, however that - * does not affect file reading. For file reading we may need to insert it into the libmap as well, - * because you might have two files indirectly linking the same datablock, and in that case - * we need this in the libmap for the fd of both those files. - * - * The crash that this check avoided earlier was because bhead->code wasn't properly passed in, making - * change_idid_adr not detect the mapping was for an ID_ID datablock. */ - oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); - change_idid_adr_fd(fd, bhead->old, id); - - // commented because this can print way too much - // if (G.debug & G_DEBUG) printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); - } + ID *id = is_yet_read(fd, libmain, bhead); - MEM_freeN(lib); - } + if (id == NULL) { + /* ID has not been read yet, add placeholder to the main of the + * library it belongs to, so that it will be read later. */ + read_libblock(fd, libmain, bhead, LIB_TAG_ID_LINK_PLACEHOLDER | LIB_TAG_INDIRECT, NULL); + // commented because this can print @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
