Initial "All" asset library loading support

An "All" asset library can be selected in the Asset Browser and asset
view templates now, and that will load all assets from all asset
libraries. Preview loading, drag & drop and asset catalogs don't work
yet.
This commit is contained in:
Julian Eisel 2022-11-22 17:56:36 +01:00
parent 67194fb247
commit 33bcc4f430
13 changed files with 140 additions and 39 deletions

View File

@ -120,6 +120,9 @@ Vector<AssetLibraryReference> all_valid_asset_library_refs();
blender::asset_system::AssetLibrary *AS_asset_library_load(
const Main *bmain, const AssetLibraryReference &library_reference);
std::string AS_asset_library_root_path_from_library_ref(
const AssetLibraryReference &library_reference);
/**
* Try to find an appropriate location for an asset library root from a file or directory path.
* Does not check if \a input_path exists.

View File

@ -64,6 +64,12 @@ bool AS_asset_library_has_any_unsaved_catalogs()
return service->has_any_unsaved_catalogs();
}
std::string AS_asset_library_root_path_from_library_ref(
const AssetLibraryReference &library_reference)
{
return AssetLibraryService::root_path_from_library_ref(library_reference);
}
std::string AS_asset_library_find_suitable_root_path_from_path(
const blender::StringRefNull input_path)
{
@ -224,6 +230,7 @@ void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data)
STRNCPY(asset_data->catalog_simple_name, catalog->simple_name.c_str());
}
/* TODO get rid of this. */
Vector<AssetLibraryReference> all_valid_asset_library_refs()
{
Vector<AssetLibraryReference> result;

View File

@ -68,12 +68,17 @@ AssetLibrary *AssetLibraryService::get_asset_library(
return get_asset_library_on_disk(root_path);
}
if (library_reference.type == ASSET_LIBRARY_CUSTOM) {
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
&U, library_reference.custom_library_index);
if (user_library) {
return get_asset_library_on_disk(user_library->path);
/* TODO */
if (library_reference.type == ASSET_LIBRARY_ALL) {
return get_asset_library_current_file();
}
if (library_reference.type == ASSET_LIBRARY_CUSTOM) {
std::string root_path = root_path_from_library_ref(library_reference);
if (!root_path.empty()) {
return get_asset_library_on_disk(root_path);
}
}
@ -133,6 +138,31 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file()
return lib;
}
std::string AssetLibraryService::root_path_from_library_ref(
const AssetLibraryReference &library_reference)
{
if (ELEM(library_reference.type, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL)) {
return "";
}
const char *top_level_directory = nullptr;
BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM);
BLI_assert(library_reference.custom_library_index >= 0);
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
&U, library_reference.custom_library_index);
if (user_library) {
top_level_directory = user_library->path;
}
if (!top_level_directory) {
return "";
}
return normalize_directory_path(top_level_directory);
}
void AssetLibraryService::allocate_service_instance()
{
instance_ = std::make_unique<AssetLibraryService>();

View File

@ -54,6 +54,8 @@ class AssetLibraryService {
/** Destroy the AssetLibraryService singleton. It will be reallocated by #get() if necessary. */
static void destroy();
static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference);
AssetLibrary *get_asset_library(const Main *bmain,
const AssetLibraryReference &library_reference);

View File

@ -30,6 +30,8 @@ class AssetStorage {
* faster lookups. Not possible until each asset is only represented once in the storage. */
StorageT local_id_assets_;
friend class AssetLibrary;
public:
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_external_asset(StringRef name, std::unique_ptr<AssetMetaData> metadata);

View File

@ -47,7 +47,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value)
if (value < ASSET_LIBRARY_CUSTOM) {
library.type = value;
library.custom_library_index = -1;
BLI_assert(ELEM(value, ASSET_LIBRARY_LOCAL));
BLI_assert(ELEM(value, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL));
return library;
}
@ -78,8 +78,11 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(
if (include_local_library) {
const EnumPropertyItem predefined_items[] = {
/* For the future. */
// {ASSET_REPO_BUNDLED, "BUNDLED", 0, "Bundled", "Show the default user assets"},
{ASSET_LIBRARY_ALL,
"ALL",
ICON_NONE,
"All",
"Show assets from all of the listed asset libraries"},
{ASSET_LIBRARY_LOCAL,
"LOCAL",
ICON_CURRENT_FILE,

View File

@ -12,6 +12,8 @@
#include <optional>
#include <string>
#include "AS_asset_library.hh"
#include "BKE_context.h"
#include "BLI_map.hh"
@ -130,16 +132,7 @@ AssetList::AssetList(eFileSelectType filesel_type, const AssetLibraryReference &
void AssetList::setup()
{
FileList *files = filelist_;
bUserAssetLibrary *user_library = nullptr;
/* Ensure valid repository, or fall-back to local one. */
if (library_ref_.type == ASSET_LIBRARY_CUSTOM) {
BLI_assert(library_ref_.custom_library_index >= 0);
user_library = BKE_preferences_asset_library_find_from_index(
&U, library_ref_.custom_library_index);
}
std::string asset_lib_path = AS_asset_library_root_path_from_library_ref(library_ref_);
/* Relevant bits from file_refresh(). */
/* TODO pass options properly. */
@ -161,13 +154,10 @@ void AssetList::setup()
filelist_setindexer(files, use_asset_indexer ? &file_indexer_asset : &file_indexer_noop);
char path[FILE_MAXDIR] = "";
if (user_library) {
BLI_strncpy(path, user_library->path, sizeof(path));
filelist_setdir(files, path);
}
else {
filelist_setdir(files, path);
if (!asset_lib_path.empty()) {
BLI_strncpy(path, asset_lib_path.c_str(), sizeof(path));
}
filelist_setdir(files, path);
}
void AssetList::fetch(const bContext &C)
@ -376,7 +366,9 @@ void AssetListStorage::remapID(ID *id_new, ID *id_old)
std::optional<eFileSelectType> AssetListStorage::asset_library_reference_to_fileselect_type(
const AssetLibraryReference &library_reference)
{
switch (library_reference.type) {
switch (eAssetLibraryType(library_reference.type)) {
case ASSET_LIBRARY_ALL:
return FILE_ASSET_LIBRARY_ALL;
case ASSET_LIBRARY_CUSTOM:
return FILE_ASSET_LIBRARY;
case ASSET_LIBRARY_LOCAL:

View File

@ -555,6 +555,7 @@ static void file_draw_preview(const SpaceFile *sfile,
/* path is no more static, cannot give it directly to but... */
else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
(file->typeflag & FILE_TYPE_ASSET) != 0) {
/* TODO enable drag & drop support, get path from asset representation. */
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {

View File

@ -320,6 +320,10 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
bool *stop,
bool *do_update,
float *progress);
static void filelist_readjob_all_asset_libraries(FileListReadJob *job_params,
bool *stop,
bool *do_update,
float *progress);
/* helper, could probably go in BKE actually? */
static int groupname_to_code(const char *group);
@ -854,13 +858,16 @@ static bool is_filtered_lib_type(FileListInternEntry *file,
const char *root,
FileListFilter *filter)
{
char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name;
if (root) {
char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name;
BLI_path_join(path, sizeof(path), root, file->relpath);
BLI_path_join(path, sizeof(path), root, file->relpath);
if (BLO_library_path_explode(path, dir, &group, &name)) {
return is_filtered_id_file_type(file, group, name, filter);
if (BLO_library_path_explode(path, dir, &group, &name)) {
return is_filtered_id_file_type(file, group, name, filter);
}
}
return is_filtered_file_type(file, filter);
}
@ -1359,11 +1366,10 @@ static bool filelist_checkdir_main(struct FileList *filelist, char *r_dir, const
return filelist_checkdir_lib(filelist, r_dir, do_change);
}
static bool filelist_checkdir_main_assets(struct FileList * /*filelist*/,
char * /*r_dir*/,
const bool /*do_change*/)
static bool filelist_checkdir_return_always_valid(struct FileList * /*filelist*/,
char * /*r_dir*/,
const bool /*do_change*/)
{
/* Main is always valid. */
return true;
}
@ -1625,6 +1631,7 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
BLI_thread_queue_push(cache->previews_done, preview);
}
else {
/* XXX */
if (entry->redirection_path) {
BLI_strncpy(preview->filepath, entry->redirection_path, FILE_MAXDIR);
}
@ -1766,12 +1773,19 @@ void filelist_settype(FileList *filelist, short type)
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA;
break;
case FILE_MAIN_ASSET:
filelist->check_dir_fn = filelist_checkdir_main_assets;
filelist->check_dir_fn = filelist_checkdir_return_always_valid;
filelist->read_job_fn = filelist_readjob_main_assets;
filelist->prepare_filter_fn = prepare_filter_asset_library;
filelist->filter_fn = is_filtered_main_assets;
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA | FILELIST_TAGS_NO_THREADS;
break;
case FILE_ASSET_LIBRARY_ALL:
filelist->check_dir_fn = filelist_checkdir_return_always_valid;
filelist->read_job_fn = filelist_readjob_all_asset_libraries;
filelist->prepare_filter_fn = prepare_filter_asset_library;
filelist->filter_fn = is_filtered_asset_library;
filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA;
break;
default:
filelist->check_dir_fn = filelist_checkdir_dir;
filelist->read_job_fn = filelist_readjob_dir;
@ -2852,6 +2866,9 @@ void filelist_entry_parent_select_set(FileList *filelist,
bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group)
{
if (filelist->asset_library) {
return true;
}
return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr);
}
@ -3746,6 +3763,10 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
*/
static bool filelist_contains_main(const FileList *filelist, const Main *bmain)
{
if (filelist->asset_library_ref && (filelist->asset_library_ref->type == ASSET_LIBRARY_ALL)) {
return true;
}
const char *blendfile_path = BKE_main_blendfile_path(bmain);
return blendfile_path[0] && BLI_path_contains(filelist->filelist.root, blendfile_path);
}
@ -3800,6 +3821,40 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress);
}
static void filelist_readjob_all_asset_libraries(FileListReadJob *job_params,
bool *stop,
bool *do_update,
float *progress)
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
(filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
filelist_readjob_load_asset_library_data(job_params, do_update);
/* A valid, but empty file-list from now. */
filelist->filelist.entries_num = 0;
filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress);
/* When only doing partialy reload for main data, we're done. */
if (job_params->only_main_data) {
return;
}
/* TODO propertly update progress? */
for (const AssetLibraryReference &library_ref : asset_system::all_valid_asset_library_refs()) {
if (library_ref.type == ASSET_LIBRARY_LOCAL) {
/* Already added main assets above. */
continue;
}
std::string library_path = AS_asset_library_root_path_from_library_ref(library_ref);
BLI_strncpy(filelist->filelist.root, library_path.c_str(), sizeof(filelist->filelist.root));
filelist_readjob_recursive_dir_add_items(true, job_params, stop, do_update, progress);
}
}
/**
* Check if the read-job is requesting a partial reread of the file list only.
*/

View File

@ -423,16 +423,20 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
}
switch (library->type) {
case ASSET_LIBRARY_ALL:
base_params->dir[0] = '\0';
base_params->type = FILE_ASSET_LIBRARY_ALL;
break;
case ASSET_LIBRARY_LOCAL:
base_params->dir[0] = '\0';
base_params->type = FILE_MAIN_ASSET;
break;
case ASSET_LIBRARY_CUSTOM:
BLI_assert(user_library);
BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir));
base_params->type = FILE_ASSET_LIBRARY;
break;
}
base_params->type = (library->type == ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET :
FILE_ASSET_LIBRARY;
}
void fileselect_refresh_params(SpaceFile *sfile)

View File

@ -21,7 +21,7 @@
#define _DNA_DEFAULT_AssetLibraryReference \
{ \
.type = ASSET_LIBRARY_LOCAL, \
/* Not needed really (should be ignored for #ASSET_LIBRARY_LOCAL), but helps debugging. */ \
/* Not needed really (should be ignored for anything but #ASSET_LIBRARY_CUSTOM), but helps debugging. */ \
.custom_library_index = -1, \
}

View File

@ -88,8 +88,7 @@ typedef enum eAssetLibraryType {
// ASSET_LIBRARY_BUNDLED = 0,
/** Display assets from the current session (current "Main"). */
ASSET_LIBRARY_LOCAL = 1,
/* For the future. Display assets for the current project. */
// ASSET_LIBRARY_PROJECT = 2,
ASSET_LIBRARY_ALL = 2,
/** Display assets from custom asset libraries, as defined in the preferences
* (#bUserAssetLibrary). The name will be taken from #FileSelectParams.asset_library_ref.idname

View File

@ -995,12 +995,15 @@ enum eFileDetails {
/** File selector types. */
typedef enum eFileSelectType {
FILE_SELECT_TYPE_UNSET = 0,
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,
/** Load all asset libraries. */
FILE_ASSET_LIBRARY_ALL = 5,
FILE_UNIX = 8,
FILE_BLENDER = 8, /* don't display relative paths */