[Bf-blender-cvs] [d28aaf6139c] master: Asset Browser: Show current file assets in other asset libraries if contained

Julian Eisel noreply at git.blender.org
Wed Oct 20 13:39:10 CEST 2021


Commit: d28aaf6139c8cfa8555542f4f228f390485dd7ed
Author: Julian Eisel
Date:   Wed Oct 20 13:09:40 2021 +0200
Branches: master
https://developer.blender.org/rBd28aaf6139c8cfa8555542f4f228f390485dd7ed

Asset Browser: Show current file assets in other asset libraries if contained

If the current file is saved within an asset library, showing that asset
library in the Asset Browser will also display the assets from this current
file now. In fact, it's the latest state of the open file, including all
unsaved modifications.
These assets will show a little Blender icon in the preview image, which is our
usual icon for current file data.

Note that this means an important design change: The "Current File" asset
library isn't the only place to edit assets from anymore. From now on assets
from the current file can also be edited in the context of the full asset
library. See T90193 for more info.

Technical info:
Besides just including the assets from the current `Main`, this requires
partial clearing and reading of file-lists, so that asset operations (e.g.
removing an asset data-block) doesn't require a full reload of the asset
library.

Maniphest Task: https://developer.blender.org/T90193

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

M	source/blender/editors/asset/intern/asset_list.cc
M	source/blender/editors/interface/interface.c
M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/space_file.c

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

diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc
index 400b3572c9b..4bc15e842fc 100644
--- a/source/blender/editors/asset/intern/asset_list.cc
+++ b/source/blender/editors/asset/intern/asset_list.cc
@@ -187,7 +187,7 @@ void AssetList::fetch(const bContext &C)
 
   if (filelist_needs_force_reset(files)) {
     filelist_readjob_stop(files, CTX_wm_manager(&C));
-    filelist_clear(files);
+    filelist_clear_from_reset_tag(files);
   }
 
   if (filelist_needs_reading(files)) {
@@ -295,9 +295,7 @@ int AssetList::size() const
 void AssetList::tagMainDataDirty() const
 {
   if (filelist_needs_reset_on_main_changes(filelist_)) {
-    /* Full refresh of the file list if local asset data was changed. Refreshing this view
-     * is cheap and users expect this to be updated immediately. */
-    filelist_tag_force_reset(filelist_);
+    filelist_tag_force_reset_mainfiles(filelist_);
   }
 }
 
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b47b63aa14c..b7458793f15 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -742,6 +742,9 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
   if (but->optype != oldbut->optype) {
     return false;
   }
+  if (but->dragtype != oldbut->dragtype) {
+    return false;
+  }
 
   if ((but->type == UI_BTYPE_TREEROW) && (oldbut->type == UI_BTYPE_TREEROW)) {
     uiButTreeRow *but_treerow = (uiButTreeRow *)but;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 9a46579780e..24b24eb81dd 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -465,6 +465,17 @@ static void file_draw_preview(const SpaceFile *sfile,
     UI_icon_draw_ex(icon_x, icon_y, icon, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
   }
 
+  const bool is_current_main_data = filelist_file_get_id(file) != NULL;
+  if (is_current_main_data) {
+    /* Smaller, fainter icon at the top-right indicating that the file represents data from the
+     * current file (from current #Main in fact). */
+    float icon_x, icon_y;
+    const uchar light[4] = {255, 255, 255, 255};
+    icon_x = xco + ex - UI_UNIT_X;
+    icon_y = yco + ey - UI_UNIT_Y;
+    UI_icon_draw_ex(icon_x, icon_y, ICON_FILE_BLEND, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
+  }
+
   /* Contrasting outline around some preview types. */
   if (show_outline) {
     GPUVertFormat *format = immVertexFormat();
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index ab274fcea62..d329a8809c7 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -435,11 +435,14 @@ typedef struct FileList {
 /* FileList.flags */
 enum {
   FL_FORCE_RESET = 1 << 0,
-  FL_IS_READY = 1 << 1,
-  FL_IS_PENDING = 1 << 2,
-  FL_NEED_SORTING = 1 << 3,
-  FL_NEED_FILTERING = 1 << 4,
-  FL_SORT_INVERT = 1 << 5,
+  /* Don't do a full reset (unless #FL_FORCE_RESET is also set), only reset files representing main
+   * data (assets from the current file/#Main). */
+  FL_FORCE_RESET_MAIN_FILES = 1 << 1,
+  FL_IS_READY = 1 << 2,
+  FL_IS_PENDING = 1 << 3,
+  FL_NEED_SORTING = 1 << 4,
+  FL_NEED_FILTERING = 1 << 5,
+  FL_SORT_INVERT = 1 << 6,
 };
 
 /* FileList.tags */
@@ -1375,6 +1378,11 @@ int ED_file_icon(const FileDirEntry *file)
                                  filelist_geticon_ex(file, NULL, false, false);
 }
 
+static bool filelist_intern_entry_is_main_file(const FileListInternEntry *intern_entry)
+{
+  return intern_entry->local_data.id != NULL;
+}
+
 /* ********** Main ********** */
 
 static void parent_dir_until_exists_or_default_root(char *dir)
@@ -1503,6 +1511,26 @@ static void filelist_intern_free(FileListIntern *filelist_intern)
   MEM_SAFE_FREE(filelist_intern->filtered);
 }
 
+/**
+ * \return the number of main files removed.
+ */
+static int filelist_intern_free_main_files(FileListIntern *filelist_intern)
+{
+  int removed_counter = 0;
+  LISTBASE_FOREACH_MUTABLE (FileListInternEntry *, entry, &filelist_intern->entries) {
+    if (!filelist_intern_entry_is_main_file(entry)) {
+      continue;
+    }
+
+    BLI_remlink(&filelist_intern->entries, entry);
+    filelist_intern_entry_free(entry);
+    removed_counter++;
+  }
+
+  MEM_SAFE_FREE(filelist_intern->filtered);
+  return removed_counter;
+}
+
 static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata)
 {
   FileListEntryCache *cache = BLI_task_pool_user_data(pool);
@@ -1803,6 +1831,7 @@ void filelist_settype(FileList *filelist, short type)
       filelist->read_job_fn = filelist_readjob_asset_library;
       filelist->prepare_filter_fn = prepare_filter_asset_library;
       filelist->filter_fn = is_filtered_asset_library;
+      filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA;
       break;
     case FILE_MAIN_ASSET:
       filelist->check_dir_fn = filelist_checkdir_main_assets;
@@ -1821,6 +1850,12 @@ void filelist_settype(FileList *filelist, short type)
   filelist->flags |= FL_FORCE_RESET;
 }
 
+static void filelist_clear_asset_library(FileList *filelist)
+{
+  /* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
+  filelist->asset_library = NULL;
+}
+
 void filelist_clear_ex(struct FileList *filelist,
                        const bool do_asset_library,
                        const bool do_cache,
@@ -1844,17 +1879,64 @@ void filelist_clear_ex(struct FileList *filelist,
     BLI_ghash_clear(filelist->selection_state, NULL, NULL);
   }
 
-  if (do_asset_library && (filelist->asset_library != NULL)) {
-    /* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
-    filelist->asset_library = NULL;
+  if (do_asset_library) {
+    filelist_clear_asset_library(filelist);
   }
 }
 
-void filelist_clear(struct FileList *filelist)
+static void filelist_clear_main_files(FileList *filelist,
+                                      const bool do_asset_library,
+                                      const bool do_cache,
+                                      const bool do_selection)
+{
+  if (!filelist || !(filelist->tags & FILELIST_TAGS_USES_MAIN_DATA)) {
+    return;
+  }
+
+  filelist_tag_needs_filtering(filelist);
+
+  if (do_cache) {
+    filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
+  }
+
+  const int removed_files = filelist_intern_free_main_files(&filelist->filelist_intern);
+
+  filelist->filelist.nbr_entries -= removed_files;
+  filelist->filelist.nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET;
+  BLI_assert(filelist->filelist.nbr_entries > FILEDIR_NBR_ENTRIES_UNSET);
+
+  if (do_selection && filelist->selection_state) {
+    BLI_ghash_clear(filelist->selection_state, NULL, NULL);
+  }
+
+  if (do_asset_library) {
+    filelist_clear_asset_library(filelist);
+  }
+}
+
+void filelist_clear(FileList *filelist)
 {
   filelist_clear_ex(filelist, true, true, true);
 }
 
+/**
+ * A "smarter" version of #filelist_clear() that calls partial clearing based on the filelist
+ * force-reset flags.
+ */
+void filelist_clear_from_reset_tag(FileList *filelist)
+{
+  /* Do a full clear if needed. */
+  if (filelist->flags & FL_FORCE_RESET) {
+    filelist_clear(filelist);
+    return;
+  }
+
+  if (filelist->flags & FL_FORCE_RESET_MAIN_FILES) {
+    filelist_clear_main_files(filelist, false, true, false);
+    return;
+  }
+}
+
 void filelist_free(struct FileList *filelist)
 {
   if (!filelist) {
@@ -1977,7 +2059,7 @@ void filelist_setrecursion(struct FileList *filelist, const int recursion_level)
 
 bool filelist_needs_force_reset(FileList *filelist)
 {
-  return (filelist->flags & FL_FORCE_RESET) != 0;
+  return (filelist->flags & (FL_FORCE_RESET | FL_FORCE_RESET_MAIN_FILES)) != 0;
 }
 
 void filelist_tag_force_reset(FileList *filelist)
@@ -1985,6 +2067,14 @@ void filelist_tag_force_reset(FileList *filelist)
   filelist->flags |= FL_FORCE_RESET;
 }
 
+void filelist_tag_force_reset_mainfiles(FileList *filelist)
+{
+  if (!(filelist->tags & FILELIST_TAGS_USES_MAIN_DATA)) {
+    return;
+  }
+  filelist->flags |= FL_FORCE_RESET_MAIN_FILES;
+}
+
 bool filelist_is_ready(struct FileList *filelist)
 {
   return (filelist->flags & FL_IS_READY) != 0;
@@ -2714,9 +2804,10 @@ int ED_file_extension_icon(const char *path)
   }
 }
 
-int filelist_needs_reading(struct FileList *filelist)
+int filelist_needs_reading(FileList *filelist)
 {
-  return (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET);
+  return (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET) ||
+         filelist_needs_force_reset(filelist);
 }
 
 uint filelist_entry_select_set(const FileList *filelist,
@@ -3279,6 +3370,9 @@ typedef struct FileListReadJob {
   char main_name[FILE_MAX];
   Main *current_main;
   struct FileList *filelist;
+  /** Set to request a partial read that only adds files representing #Main data (IDs). Used when
+   * #Main may have received changes of interest (e.g. asset removed or renamed). */
+  bool only_main_data;
 
   /** Shallow copy of #filelist for thread-safe access.
    *
@@ -3293,6 +3387,26 @@ typedef struct FileListReadJob {
   struct FileList *tmp_filelist;
 } FileListReadJob;
 
+static void filelist_readjob_append_entries(FileListReadJob *job_params,
+                                            ListBase *from_entries,
+                                            int nbr_from_entries,
+                                            short *do_update)
+{
+  BLI_assert(BLI_listbase_count(from_entries) == nbr_from_entries);
+  if (nbr_from_entries <= 0) {
+    *do_update = false;
+    return;
+  }
+
+  FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
+  BLI_mutex_lock(&job_params->lock);
+  BLI_movelisttolist(&filelist->filelist.entries, from_entries);
+  filelist->filelist.nbr_entries += nbr_from_entries;
+  BLI_mutex_unlock(&job_params->lock);
+
+  *do_update = true;
+}
+
 static bool filelist_readjob_should_recurse_into_entry(const int max_recursion,
                       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list