Use "All" library for node add menu building
Code was manually building the add menu from all asset libraries, this should be simpler now.
This commit is contained in:
parent
a07a2e2369
commit
ecc25bc62e
|
@ -15,6 +15,18 @@ struct AssetLibraryReference;
|
|||
struct FileDirEntry;
|
||||
struct bContext;
|
||||
|
||||
namespace blender::asset_system {
|
||||
class AssetLibrary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the asset library being read into an asset-list and identified using \a library_reference.
|
||||
* \note The asset library may be loaded asynchronously, so this may return null until it becomes
|
||||
* available.
|
||||
*/
|
||||
blender::asset_system::AssetLibrary *ED_assetlist_library_get(
|
||||
const AssetLibraryReference &library_reference);
|
||||
|
||||
/* Can return false to stop iterating. */
|
||||
using AssetListIterFn = blender::FunctionRef<bool(AssetHandle)>;
|
||||
void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn);
|
||||
|
|
|
@ -114,6 +114,7 @@ class AssetList : NonCopyable {
|
|||
void clear(bContext *C);
|
||||
|
||||
bool needsRefetch() const;
|
||||
asset_system::AssetLibrary *asset_library() const;
|
||||
void iterate(AssetListIterFn fn) const;
|
||||
bool listen(const wmNotifier ¬ifier) const;
|
||||
int size() const;
|
||||
|
@ -180,6 +181,11 @@ bool AssetList::needsRefetch() const
|
|||
return filelist_needs_force_reset(filelist_) || filelist_needs_reading(filelist_);
|
||||
}
|
||||
|
||||
asset_system::AssetLibrary *AssetList::asset_library() const
|
||||
{
|
||||
return reinterpret_cast<asset_system::AssetLibrary *>(filelist_asset_library(filelist_));
|
||||
}
|
||||
|
||||
void AssetList::iterate(AssetListIterFn fn) const
|
||||
{
|
||||
FileList *files = filelist_;
|
||||
|
@ -399,6 +405,7 @@ AssetListStorage::AssetListMap &AssetListStorage::global_storage()
|
|||
/** \name C-API
|
||||
* \{ */
|
||||
|
||||
using namespace blender;
|
||||
using namespace blender::ed::asset;
|
||||
|
||||
void ED_assetlist_storage_fetch(const AssetLibraryReference *library_reference, const bContext *C)
|
||||
|
@ -449,6 +456,16 @@ void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetL
|
|||
}
|
||||
}
|
||||
|
||||
asset_system::AssetLibrary *ED_assetlist_library_get(
|
||||
const AssetLibraryReference &library_reference)
|
||||
{
|
||||
const AssetList *list = AssetListStorage::lookup_list(library_reference);
|
||||
if (!list) {
|
||||
return nullptr;
|
||||
}
|
||||
return list->asset_library();
|
||||
}
|
||||
|
||||
ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
|
||||
{
|
||||
ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data);
|
||||
|
|
|
@ -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(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
|
||||
|
|
Loading…
Reference in New Issue