diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_blendfile_link_append.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blendfile_link_append.c | 96 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files_link.c | 14 |
3 files changed, 87 insertions, 27 deletions
diff --git a/source/blender/blenkernel/BKE_blendfile_link_append.h b/source/blender/blenkernel/BKE_blendfile_link_append.h index e0e38390a70..2035f69315c 100644 --- a/source/blender/blenkernel/BKE_blendfile_link_append.h +++ b/source/blender/blenkernel/BKE_blendfile_link_append.h @@ -23,6 +23,7 @@ extern "C" { #endif +struct BlendHandle; struct ID; struct Library; struct LibraryLink_Params; @@ -50,7 +51,8 @@ void BKE_blendfile_link_append_context_embedded_blendfile_clear( struct BlendfileLinkAppendContext *lapp_context); void BKE_blendfile_link_append_context_library_add(struct BlendfileLinkAppendContext *lapp_context, - const char *libname); + const char *libname, + struct BlendHandle *blo_handle); struct BlendfileLinkAppendContextItem *BKE_blendfile_link_append_context_item_add( struct BlendfileLinkAppendContext *lapp_context, const char *idname, diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 3ba2287bb0e..062aa6d34aa 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -94,6 +94,15 @@ typedef struct BlendfileLinkAppendContextItem { void *userdata; } BlendfileLinkAppendContextItem; +/* A blendfile library entry in the `libraries` list of #BlendfileLinkAppendContext. */ +typedef struct BlendfileLinkAppendContextLibrary { + char *path; /* Absolute .blend file path. */ + BlendHandle *blo_handle; /* Blend file handle, if any. */ + bool blo_handle_is_owned; /* Whether the blend file handle is owned, or borrowed. */ + /* The blendfile report associated with the `blo_handle`, if owned. */ + BlendFileReadReport bf_reports; +} BlendfileLinkAppendContextLibrary; + typedef struct BlendfileLinkAppendContext { /** List of library paths to search IDs in. */ LinkNodePair libraries; @@ -140,6 +149,43 @@ enum { LINK_APPEND_TAG_INDIRECT = 1 << 0, }; +static BlendHandle *link_append_context_library_blohandle_ensure( + BlendfileLinkAppendContext *lapp_context, + BlendfileLinkAppendContextLibrary *lib_context, + ReportList *reports) +{ + if (reports != NULL) { + lib_context->bf_reports.reports = reports; + } + + char *libname = lib_context->path; + BlendHandle *blo_handle = lib_context->blo_handle; + if (blo_handle == NULL) { + if (STREQ(libname, BLO_EMBEDDED_STARTUP_BLEND)) { + blo_handle = BLO_blendhandle_from_memory(lapp_context->blendfile_mem, + (int)lapp_context->blendfile_memsize, + &lib_context->bf_reports); + } + else { + blo_handle = BLO_blendhandle_from_file(libname, &lib_context->bf_reports); + } + lib_context->blo_handle = blo_handle; + lib_context->blo_handle_is_owned = true; + } + + return blo_handle; +} + +static void link_append_context_library_blohandle_release( + BlendfileLinkAppendContext *UNUSED(lapp_context), + BlendfileLinkAppendContextLibrary *lib_context) +{ + if (lib_context->blo_handle_is_owned && lib_context->blo_handle != NULL) { + BLO_blendhandle_close(lib_context->blo_handle); + lib_context->blo_handle = NULL; + } +} + /** Allocate and initialize a new context to link/append datablocks. * * \param flag a combination of #eFileSel_Params_Flag from DNA_space_types.h & #eBLOLibLinkFlags @@ -163,6 +209,12 @@ void BKE_blendfile_link_append_context_free(BlendfileLinkAppendContext *lapp_con BLI_ghash_free(lapp_context->new_id_to_item, NULL, NULL); } + for (LinkNode *liblink = lapp_context->libraries.list; liblink != NULL; + liblink = liblink->next) { + BlendfileLinkAppendContextLibrary *lib_context = liblink->link; + link_append_context_library_blohandle_release(lapp_context, lib_context); + } + BLI_assert(lapp_context->library_weak_reference_mapping == NULL); BLI_memarena_free(lapp_context->memarena); @@ -209,18 +261,31 @@ void BKE_blendfile_link_append_context_embedded_blendfile_clear( /** Add a new source library to search for items to be linked to the given link/append context. * + * \param libname: the absolute path to the library blend file. + * \param blo_handle: the blend file handle of the library, NULL is not available. Note that this + * is only borrowed for linking purpose, no releasing or other management will + * be performed by #BKE_blendfile_link_append code on it. + * * \note *Never* call BKE_blendfile_link_append_context_library_add() after having added some * items. */ void BKE_blendfile_link_append_context_library_add(BlendfileLinkAppendContext *lapp_context, - const char *libname) + const char *libname, + BlendHandle *blo_handle) { BLI_assert(lapp_context->items.list == NULL); + BlendfileLinkAppendContextLibrary *lib_context = BLI_memarena_calloc(lapp_context->memarena, + sizeof(*lib_context)); + size_t len = strlen(libname) + 1; char *libpath = BLI_memarena_alloc(lapp_context->memarena, len); - BLI_strncpy(libpath, libname, len); - BLI_linklist_append_arena(&lapp_context->libraries, libpath, lapp_context->memarena); + + lib_context->path = libpath; + lib_context->blo_handle = blo_handle; + lib_context->blo_handle_is_owned = (blo_handle == NULL); + + BLI_linklist_append_arena(&lapp_context->libraries, lib_context, lapp_context->memarena); lapp_context->num_libraries++; } @@ -1076,7 +1141,6 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList * void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports) { Main *mainl; - BlendHandle *bh; Library *lib; LinkNode *liblink, *itemlink; @@ -1086,18 +1150,12 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re for (lib_idx = 0, liblink = lapp_context->libraries.list; liblink; lib_idx++, liblink = liblink->next) { - char *libname = liblink->link; - BlendFileReadReport bf_reports = {.reports = reports}; - - if (STREQ(libname, BLO_EMBEDDED_STARTUP_BLEND)) { - bh = BLO_blendhandle_from_memory( - lapp_context->blendfile_mem, (int)lapp_context->blendfile_memsize, &bf_reports); - } - else { - bh = BLO_blendhandle_from_file(libname, &bf_reports); - } + BlendfileLinkAppendContextLibrary *lib_context = liblink->link; + char *libname = lib_context->path; + BlendHandle *blo_handle = link_append_context_library_blohandle_ensure( + lapp_context, lib_context, reports); - if (bh == NULL) { + if (blo_handle == NULL) { /* Unlikely since we just browsed it, but possible * Error reports will have been made by BLO_blendhandle_from_file() */ continue; @@ -1111,7 +1169,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re * #loose_data_instantiate instead. */ lapp_context->params->flag &= ~BLO_LIBLINK_NEEDS_ID_TAG_DOIT; - mainl = BLO_library_link_begin(&bh, libname, lapp_context->params); + mainl = BLO_library_link_begin(&blo_handle, libname, lapp_context->params); lib = mainl->curlib; BLI_assert(lib); UNUSED_VARS_NDEBUG(lib); @@ -1138,7 +1196,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re } new_id = BLO_library_link_named_part( - mainl, &bh, item->idcode, item->name, lapp_context->params); + mainl, &blo_handle, item->idcode, item->name, lapp_context->params); if (new_id) { /* If the link is successful, clear item's libs 'todo' flags. @@ -1149,8 +1207,8 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re } } - BLO_library_link_end(mainl, &bh, lapp_context->params); - BLO_blendhandle_close(bh); + BLO_library_link_end(mainl, &blo_handle, lapp_context->params); + link_append_context_library_blohandle_release(lapp_context, lib_context); } /* Instantiate newly linked IDs as needed, if no append is scheduled. */ diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 7cb91bf4c0f..00ac1c2ffe6 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -309,7 +309,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) if (!BLI_ghash_haskey(libraries, libname)) { BLI_ghash_insert(libraries, BLI_strdup(libname), POINTER_FROM_INT(lib_idx)); lib_idx++; - BKE_blendfile_link_append_context_library_add(lapp_context, libname); + BKE_blendfile_link_append_context_library_add(lapp_context, libname, NULL); } } } @@ -341,7 +341,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) else { BlendfileLinkAppendContextItem *item; - BKE_blendfile_link_append_context_library_add(lapp_context, libname); + BKE_blendfile_link_append_context_library_add(lapp_context, libname, NULL); item = BKE_blendfile_link_append_context_item_add( lapp_context, name, BKE_idtype_idcode_from_name(group), NULL); BKE_blendfile_link_append_context_item_library_index_enable(lapp_context, item, 0); @@ -530,7 +530,7 @@ static ID *wm_file_link_append_datablock_ex(Main *bmain, BKE_blendfile_link_append_context_embedded_blendfile_set( lapp_context, datatoc_startup_blend, datatoc_startup_blend_size); - BKE_blendfile_link_append_context_library_add(lapp_context, filepath); + BKE_blendfile_link_append_context_library_add(lapp_context, filepath, NULL); BlendfileLinkAppendContextItem *item = BKE_blendfile_link_append_context_item_add( lapp_context, id_name, id_code, NULL); BKE_blendfile_link_append_context_item_library_index_enable(lapp_context, item, 0); @@ -651,7 +651,7 @@ void WM_lib_reload(Library *lib, bContext *C, ReportList *reports) BlendfileLinkAppendContext *lapp_context = BKE_blendfile_link_append_context_new(&lapp_params); - BKE_blendfile_link_append_context_library_add(lapp_context, lib->filepath_abs); + BKE_blendfile_link_append_context_library_add(lapp_context, lib->filepath_abs, NULL); BKE_blendfile_library_relocate(lapp_context, reports, lib, true); @@ -736,7 +736,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) do_reload = true; lapp_context = BKE_blendfile_link_append_context_new(&lapp_params); - BKE_blendfile_link_append_context_library_add(lapp_context, path); + BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); } else { int totfiles = 0; @@ -769,13 +769,13 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) } CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", path); - BKE_blendfile_link_append_context_library_add(lapp_context, path); + BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); } RNA_END; } else { CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", path); - BKE_blendfile_link_append_context_library_add(lapp_context, path); + BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); } } |