BKE link/append: Add optional blendfile handle to libraries.
This enables calling code to deal with the blendfile handle themselves, BKE_blendfile_link then just borrows, uses this handle and does not release it. Needed e.g. for python's libcontext system to use new BKE_blendfile_link_append code. Part of T91414: Unify link/append between WM operators and BPY context manager API, and cleanup usages of `BKE_library_make_local`.
This commit is contained in:
parent
f657356062
commit
fbb4a7eb43
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
@ -208,19 +260,32 @@ 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};
|
||||
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 (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);
|
||||
}
|
||||
|
||||
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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue