Refactor: Use new "All" asset library to extend node menus with assets

Updates the add and search menu of the node editor to use the new "All"
asset library introduced in the previous commit. This simplifies code by
removing redundant logic to merge contents of multiple asset libraries.
This commit is contained in:
Julian Eisel 2023-01-10 15:37:31 +01:00
parent 35e54b52e6
commit 66af16571d
2 changed files with 57 additions and 93 deletions

View File

@ -49,13 +49,6 @@ struct LibraryAsset {
AssetHandle handle;
};
struct LibraryCatalog {
asset_system::AssetLibrary *library;
/* Catalog pointers are not save to store. Use the catalog ID instead and lookup the catalog when
* needed. */
const asset_system::CatalogID catalog_id;
};
struct AssetItemTree {
asset_system::AssetCatalogTree catalogs;
MultiValueMap<asset_system::AssetCatalogPath, LibraryAsset> assets_per_path;
@ -63,14 +56,18 @@ struct AssetItemTree {
full_catalog_per_tree_item;
};
static AssetLibraryReference all_library_reference()
{
AssetLibraryReference all_library_ref{};
all_library_ref.custom_library_index = -1;
all_library_ref.type = ASSET_LIBRARY_ALL;
return all_library_ref;
}
static bool all_loading_finished()
{
for (const AssetLibraryReference &library : asset_system::all_valid_asset_library_refs()) {
if (!ED_assetlist_is_loaded(&library)) {
return false;
}
}
return true;
AssetLibraryReference all_library_ref = all_library_reference();
return ED_assetlist_is_loaded(&all_library_ref);
}
static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node_tree)
@ -78,68 +75,52 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
if (!node_tree) {
return {};
}
const Main &bmain = *CTX_data_main(&C);
const Vector<AssetLibraryReference> all_libraries = asset_system::all_valid_asset_library_refs();
/* Merge catalogs from all libraries to deduplicate menu items. Also store the catalog and
* library for each asset ID in order to use them later when retrieving assets and removing
* empty catalogs. */
Map<asset_system::CatalogID, LibraryCatalog> id_to_catalog_map;
asset_system::AssetCatalogTree catalogs_from_all_libraries;
for (const AssetLibraryReference &library_ref : all_libraries) {
if (asset_system::AssetLibrary *library = AS_asset_library_load(&bmain, library_ref)) {
if (asset_system::AssetCatalogTree *tree = library->catalog_service->get_catalog_tree()) {
tree->foreach_item([&](asset_system::AssetCatalogTreeItem &item) {
const asset_system::CatalogID &id = item.get_catalog_id();
asset_system::AssetCatalog *catalog = library->catalog_service->find_catalog(id);
catalogs_from_all_libraries.insert_item(*catalog);
id_to_catalog_map.add(item.get_catalog_id(), LibraryCatalog{library, id});
});
}
}
}
/* Find all the matching node group assets for every catalog path. */
MultiValueMap<asset_system::AssetCatalogPath, LibraryAsset> assets_per_path;
for (const AssetLibraryReference &library_ref : all_libraries) {
AssetFilterSettings type_filter{};
type_filter.id_types = FILTER_ID_NT;
ED_assetlist_storage_fetch(&library_ref, &C);
ED_assetlist_ensure_previews_job(&library_ref, &C);
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
if (!ED_asset_filter_matches_asset(&type_filter, &asset)) {
return true;
}
const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset);
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type");
if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) {
return true;
}
if (BLI_uuid_is_nil(meta_data.catalog_id)) {
return true;
}
const LibraryCatalog *library_catalog = id_to_catalog_map.lookup_ptr(meta_data.catalog_id);
if (library_catalog == nullptr) {
return true;
}
const asset_system::AssetCatalog *catalog =
library_catalog->library->catalog_service->find_catalog(library_catalog->catalog_id);
assets_per_path.add(catalog->path, LibraryAsset{library_ref, asset});
return true;
});
AssetFilterSettings type_filter{};
type_filter.id_types = FILTER_ID_NT;
const AssetLibraryReference all_library_ref = all_library_reference();
ED_assetlist_storage_fetch(&all_library_ref, &C);
ED_assetlist_ensure_previews_job(&all_library_ref, &C);
asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(all_library_ref);
if (!all_library) {
return {};
}
/* Build the final tree without any of the catalogs that don't have proper node group assets. */
asset_system::AssetCatalogTree catalogs_with_node_assets;
catalogs_from_all_libraries.foreach_item([&](asset_system::AssetCatalogTreeItem &item) {
if (!assets_per_path.lookup(item.catalog_path()).is_empty()) {
const asset_system::CatalogID &id = item.get_catalog_id();
const LibraryCatalog &library_catalog = id_to_catalog_map.lookup(id);
asset_system::AssetCatalog *catalog = library_catalog.library->catalog_service->find_catalog(
id);
catalogs_with_node_assets.insert_item(*catalog);
ED_assetlist_iterate(all_library_ref, [&](AssetHandle asset) {
if (!ED_asset_filter_matches_asset(&type_filter, &asset)) {
return true;
}
const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset);
const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type");
if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) {
return true;
}
if (BLI_uuid_is_nil(meta_data.catalog_id)) {
return true;
}
const asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog(
meta_data.catalog_id);
assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, asset});
return true;
});
/* Build an own tree without any of the catalogs that don't have proper node group assets. */
asset_system::AssetCatalogTree catalogs_with_node_assets;
asset_system::AssetCatalogTree &catalog_tree = *all_library->catalog_service->get_catalog_tree();
catalog_tree.foreach_item([&](asset_system::AssetCatalogTreeItem &item) {
if (assets_per_path.lookup(item.catalog_path()).is_empty()) {
return;
}
asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog(
item.get_catalog_id());
catalogs_with_node_assets.insert_item(*catalog);
});
/* Build another map storing full asset paths for each tree item, in order to have stable

View File

@ -93,12 +93,15 @@ static void search_items_for_asset_metadata(const bNodeTree &node_tree,
search_items.append(std::move(item));
}
static void gather_search_items_for_asset_library(const bContext &C,
const bNodeTree &node_tree,
const AssetLibraryReference &library_ref,
Set<std::string> &r_added_assets,
Vector<AddNodeItem> &search_items)
static void gather_search_items_for_all_assets(const bContext &C,
const bNodeTree &node_tree,
Set<std::string> &r_added_assets,
Vector<AddNodeItem> &search_items)
{
AssetLibraryReference library_ref{};
library_ref.custom_library_index = -1;
library_ref.type = ASSET_LIBRARY_ALL;
AssetFilterSettings filter_settings{};
filter_settings.id_types = FILTER_ID_NT;
@ -117,26 +120,6 @@ static void gather_search_items_for_asset_library(const bContext &C,
});
}
static void gather_search_items_for_all_assets(const bContext &C,
const bNodeTree &node_tree,
Set<std::string> &r_added_assets,
Vector<AddNodeItem> &search_items)
{
int i;
LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
AssetLibraryReference library_ref{};
library_ref.custom_library_index = i;
library_ref.type = ASSET_LIBRARY_CUSTOM;
/* Skip local assets to avoid duplicates when the asset is part of the local file library. */
gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items);
}
AssetLibraryReference library_ref{};
library_ref.custom_library_index = -1;
library_ref.type = ASSET_LIBRARY_LOCAL;
gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items);
}
static void gather_search_items_for_node_groups(const bContext &C,
const bNodeTree &node_tree,
const Set<std::string> &local_assets,