Assets: Read catalogs immediately when loading a library

Until now, the asset catalogs would only show up after all assets from
the library were loaded. Now the catalogs are read first, which makes
them appear pretty much immediately. This makes the UI more responsive
and feel less heavy.

I added a dedicated file-list type for asset libraries now. While not
necessarily needed, I prefer that so asset library specific stuff can be
handled in there.
This commit is contained in:
Julian Eisel 2021-09-24 20:12:07 +02:00
parent be16794ba1
commit c87e6b23be
5 changed files with 58 additions and 22 deletions

View File

@ -390,7 +390,7 @@ std::optional<eFileSelectType> AssetListStorage::asset_library_reference_to_file
{
switch (library_reference.type) {
case ASSET_LIBRARY_CUSTOM:
return FILE_LOADLIB;
return FILE_ASSET_LIBRARY;
case ASSET_LIBRARY_LOCAL:
return FILE_MAIN_ASSET;
}

View File

@ -473,6 +473,10 @@ static void filelist_readjob_dir(struct FileListReadJob *job_params,
short *stop,
short *do_update,
float *progress);
static void filelist_readjob_asset_library(struct FileListReadJob *job_params,
short *stop,
short *do_update,
float *progress);
static void filelist_readjob_main_assets(struct FileListReadJob *job_params,
short *stop,
short *do_update,
@ -1725,6 +1729,11 @@ void filelist_settype(FileList *filelist, short type)
filelist->read_job_fn = filelist_readjob_lib;
filelist->filter_fn = is_filtered_lib;
break;
case FILE_ASSET_LIBRARY:
filelist->check_dir_fn = filelist_checkdir_lib;
filelist->read_job_fn = filelist_readjob_asset_library;
filelist->filter_fn = is_filtered_lib;
break;
case FILE_MAIN_ASSET:
filelist->check_dir_fn = filelist_checkdir_main_assets;
filelist->read_job_fn = filelist_readjob_main_assets;
@ -1741,7 +1750,10 @@ void filelist_settype(FileList *filelist, short type)
filelist->flags |= FL_FORCE_RESET;
}
void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection)
void filelist_clear_ex(struct FileList *filelist,
const bool do_asset_library,
const bool do_cache,
const bool do_selection)
{
if (!filelist) {
return;
@ -1761,7 +1773,7 @@ void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const boo
BLI_ghash_clear(filelist->selection_state, NULL, NULL);
}
if (filelist->asset_library != NULL) {
if (do_asset_library && (filelist->asset_library != NULL)) {
/* There is no way to refresh the catalogs stored by the AssetLibrary struct, so instead of
* "clearing" it, the entire struct is freed. It will be reallocated when needed. */
BKE_asset_library_free(filelist->asset_library);
@ -1771,7 +1783,7 @@ void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const boo
void filelist_clear(struct FileList *filelist)
{
filelist_clear_ex(filelist, true, true);
filelist_clear_ex(filelist, true, true, true);
}
void filelist_free(struct FileList *filelist)
@ -1782,7 +1794,7 @@ void filelist_free(struct FileList *filelist)
}
/* No need to clear cache & selection_state, we free them anyway. */
filelist_clear_ex(filelist, false, false);
filelist_clear_ex(filelist, true, false, false);
filelist_cache_free(&filelist->filelist_cache);
if (filelist->selection_state) {
@ -3368,13 +3380,6 @@ static void filelist_readjob_do(const bool do_lib,
BLI_stack_discard(todo_dirs);
}
BLI_stack_free(todo_dirs);
/* Check whether assets catalogs need to be loaded. */
if (job_params->filelist->asset_library_ref != NULL) {
/* Load asset catalogs, into the temp filelist for thread-safety.
* #filelist_readjob_endjob() will move it into the real filelist. */
job_params->tmp_filelist->asset_library = BKE_asset_library_load(filelist->filelist.root);
}
}
static void filelist_readjob_dir(FileListReadJob *job_params,
@ -3393,6 +3398,28 @@ static void filelist_readjob_lib(FileListReadJob *job_params,
filelist_readjob_do(true, job_params, stop, do_update, progress);
}
static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params, short *do_update)
{
FileList *tmp_filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
/* Check whether assets catalogs need to be loaded. */
if (job_params->filelist->asset_library_ref != NULL) {
/* Load asset catalogs, into the temp filelist for thread-safety.
* #filelist_readjob_endjob() will move it into the real filelist. */
tmp_filelist->asset_library = BKE_asset_library_load(tmp_filelist->filelist.root);
*do_update = true;
}
}
static void filelist_readjob_asset_library(FileListReadJob *job_params,
short *stop,
short *do_update,
float *progress)
{
filelist_readjob_load_asset_library_data(job_params, do_update);
filelist_readjob_lib(job_params, stop, do_update, progress);
}
static void filelist_readjob_main(FileListReadJob *job_params,
short *stop,
short *do_update,
@ -3414,6 +3441,8 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
(filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET));
filelist_readjob_load_asset_library_data(job_params, do_update);
/* A valid, but empty directory from now. */
filelist->filelist.nbr_entries = 0;
@ -3505,11 +3534,17 @@ static void filelist_readjob_update(void *flrjv)
flrj->tmp_filelist->filelist.nbr_entries = 0;
}
if (flrj->tmp_filelist->asset_library) {
flrj->filelist->asset_library = flrj->tmp_filelist->asset_library;
flrj->tmp_filelist->asset_library = NULL; /* MUST be NULL to avoid double-free. */
}
BLI_mutex_unlock(&flrj->lock);
if (new_nbr_entries) {
/* Do not clear selection cache, we can assume already 'selected' UIDs are still valid! */
filelist_clear_ex(flrj->filelist, true, false);
/* Do not clear selection cache, we can assume already 'selected' UIDs are still valid! Keep
* the asset library data we just read. */
filelist_clear_ex(flrj->filelist, false, true, false);
flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
}
@ -3526,12 +3561,6 @@ static void filelist_readjob_endjob(void *flrjv)
/* In case there would be some dangling update... */
filelist_readjob_update(flrjv);
/* Move ownership of the asset library from the temporary list to the true filelist. */
BLI_assert_msg(flrj->filelist->asset_library == NULL,
"asset library should not already have been allocated");
flrj->filelist->asset_library = flrj->tmp_filelist->asset_library;
flrj->tmp_filelist->asset_library = NULL; /* MUST be NULL to avoid double-free. */
flrj->filelist->flags &= ~FL_IS_PENDING;
flrj->filelist->flags |= FL_IS_READY;
}

View File

@ -86,7 +86,10 @@ int filelist_geticon(struct FileList *filelist, const int index, const bool is_m
struct FileList *filelist_new(short type);
void filelist_settype(struct FileList *filelist, short type);
void filelist_clear(struct FileList *filelist);
void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection);
void filelist_clear_ex(struct FileList *filelist,
const bool do_asset_library,
const bool do_cache,
const bool do_selection);
void filelist_free(struct FileList *filelist);
const char *filelist_dir(struct FileList *filelist);

View File

@ -440,7 +440,8 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir));
break;
}
base_params->type = (library->type == ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET : FILE_LOADLIB;
base_params->type = (library->type == ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET :
FILE_ASSET_LIBRARY;
}
void fileselect_refresh_params(SpaceFile *sfile)

View File

@ -965,7 +965,10 @@ enum eFileDetails {
typedef enum eFileSelectType {
FILE_LOADLIB = 1,
FILE_MAIN = 2,
/** Load assets from #Main. */
FILE_MAIN_ASSET = 3,
/** Load assets of an asset library containing external files. */
FILE_ASSET_LIBRARY = 4,
FILE_UNIX = 8,
FILE_BLENDER = 8, /* don't display relative paths */