[Bf-blender-cvs] [fbb4a7eb434] master: BKE link/append: Add optional blendfile handle to libraries.

Bastien Montagne noreply at git.blender.org
Tue Nov 23 10:39:34 CET 2021


Commit: fbb4a7eb434f57e03fd274b107b466919cdd049a
Author: Bastien Montagne
Date:   Wed Nov 10 11:24:59 2021 +0100
Branches: master
https://developer.blender.org/rBfbb4a7eb434f57e03fd274b107b466919cdd049a

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`.

===================================================================

M	source/blender/blenkernel/BKE_blendfile_link_append.h
M	source/blender/blenkernel/intern/blendfile_link_append.c
M	source/blender/windowmanager/intern/wm_files_link.c

===================================================================

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);
@@ -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};
-
-    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_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list