Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_asset_catalog.hh18
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc31
-rw-r--r--source/blender/blenkernel/intern/asset_catalog_test.cc58
-rw-r--r--source/blender/editors/asset/intern/asset_catalog.cc2
4 files changed, 100 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh
index bd18fdf1d6e..4ea6abd65e0 100644
--- a/source/blender/blenkernel/BKE_asset_catalog.hh
+++ b/source/blender/blenkernel/BKE_asset_catalog.hh
@@ -117,9 +117,21 @@ class AssetCatalogService {
AssetCatalog *create_catalog(const AssetCatalogPath &catalog_path);
/**
- * Soft-delete the catalog, ensuring it actually gets deleted when the catalog definition file is
- * written. */
- void delete_catalog(CatalogID catalog_id);
+ * Delete all catalogs with the given path, and their children.
+ */
+ void prune_catalogs_by_path(const AssetCatalogPath &path);
+
+ /**
+ * Delete all catalogs with the same path as the identified catalog, and their children.
+ * This call is the same as calling `prune_catalogs_by_path(find_catalog(catalog_id)->path)`.
+ */
+ void prune_catalogs_by_id(CatalogID catalog_id);
+
+ /**
+ * Delete a catalog, without deleting any of its children and without rebuilding the catalog
+ * tree. This is a lower-level function than #prune_catalogs_by_path.
+ */
+ void delete_catalog_by_id(CatalogID catalog_id);
/**
* Update the catalog path, also updating the catalog path of all sub-catalogs.
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index ab7d8eafb8b..4531dabf0cf 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -112,7 +112,7 @@ AssetCatalogFilter AssetCatalogService::create_catalog_filter(
return AssetCatalogFilter(std::move(matching_catalog_ids));
}
-void AssetCatalogService::delete_catalog(CatalogID catalog_id)
+void AssetCatalogService::delete_catalog_by_id(const CatalogID catalog_id)
{
std::unique_ptr<AssetCatalog> *catalog_uptr_ptr = this->catalogs_.lookup_ptr(catalog_id);
if (catalog_uptr_ptr == nullptr) {
@@ -129,11 +129,38 @@ void AssetCatalogService::delete_catalog(CatalogID catalog_id)
/* The catalog can now be removed from the map without freeing the actual AssetCatalog. */
this->catalogs_.remove(catalog_id);
+}
+
+void AssetCatalogService::prune_catalogs_by_path(const AssetCatalogPath &path)
+{
+ /* Build a collection of catalog IDs to delete. */
+ Set<CatalogID> catalogs_to_delete;
+ for (const auto &catalog_uptr : this->catalogs_.values()) {
+ const AssetCatalog *cat = catalog_uptr.get();
+ if (cat->path.is_contained_in(path)) {
+ catalogs_to_delete.add(cat->catalog_id);
+ }
+ }
+
+ /* Delete the catalogs. */
+ for (const CatalogID cat_id : catalogs_to_delete) {
+ this->delete_catalog_by_id(cat_id);
+ }
this->rebuild_tree();
}
-void AssetCatalogService::update_catalog_path(CatalogID catalog_id,
+void AssetCatalogService::prune_catalogs_by_id(const CatalogID catalog_id)
+{
+ const AssetCatalog *catalog = find_catalog(catalog_id);
+ BLI_assert_msg(catalog, "trying to prune asset catalogs by the path of a non-existent catalog");
+ if (!catalog) {
+ return;
+ }
+ this->prune_catalogs_by_path(catalog->path);
+}
+
+void AssetCatalogService::update_catalog_path(const CatalogID catalog_id,
const AssetCatalogPath &new_catalog_path)
{
AssetCatalog *renamed_cat = this->find_catalog(catalog_id);
diff --git a/source/blender/blenkernel/intern/asset_catalog_test.cc b/source/blender/blenkernel/intern/asset_catalog_test.cc
index 69efab76b43..cf06638bcdd 100644
--- a/source/blender/blenkernel/intern/asset_catalog_test.cc
+++ b/source/blender/blenkernel/intern/asset_catalog_test.cc
@@ -719,7 +719,7 @@ TEST_F(AssetCatalogTest, delete_catalog_leaf)
/* Delete a leaf catalog, i.e. one that is not a parent of another catalog.
* This keeps this particular test easy. */
- service.delete_catalog(UUID_POSES_RUZENA_HAND);
+ service.prune_catalogs_by_id(UUID_POSES_RUZENA_HAND);
EXPECT_EQ(nullptr, service.find_catalog(UUID_POSES_RUZENA_HAND));
/* Contains not only paths from the CDF but also the missing parents (implicitly defined
@@ -743,13 +743,65 @@ TEST_F(AssetCatalogTest, delete_catalog_leaf)
assert_expected_tree_items(tree, expected_paths);
}
+TEST_F(AssetCatalogTest, delete_catalog_parent_by_id)
+{
+ AssetCatalogService service(asset_library_root_);
+ service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+
+ /* Delete a parent catalog. */
+ service.delete_catalog_by_id(UUID_POSES_RUZENA);
+
+ /* The catalog should have been deleted, but its children should still be there. */
+ EXPECT_EQ(nullptr, service.find_catalog(UUID_POSES_RUZENA));
+ EXPECT_NE(nullptr, service.find_catalog(UUID_POSES_RUZENA_FACE));
+ EXPECT_NE(nullptr, service.find_catalog(UUID_POSES_RUZENA_HAND));
+}
+
+TEST_F(AssetCatalogTest, delete_catalog_parent_by_path)
+{
+ AssetCatalogService service(asset_library_root_);
+ service.load_from_disk(asset_library_root_ + "/" + "blender_assets.cats.txt");
+
+ /* Create an extra catalog with the to-be-deleted path, and one with a child of that.
+ * This creates some duplicates that are bound to occur in production asset libraries as well. */
+ const bUUID cat1_uuid = service.create_catalog("character/Ružena/poselib")->catalog_id;
+ const bUUID cat2_uuid = service.create_catalog("character/Ružena/poselib/body")->catalog_id;
+
+ /* Delete a parent catalog. */
+ service.prune_catalogs_by_path("character/Ružena/poselib");
+
+ /* The catalogs and their children should have been deleted. */
+ EXPECT_EQ(nullptr, service.find_catalog(UUID_POSES_RUZENA));
+ EXPECT_EQ(nullptr, service.find_catalog(UUID_POSES_RUZENA_FACE));
+ EXPECT_EQ(nullptr, service.find_catalog(UUID_POSES_RUZENA_HAND));
+ EXPECT_EQ(nullptr, service.find_catalog(cat1_uuid));
+ EXPECT_EQ(nullptr, service.find_catalog(cat2_uuid));
+
+ /* Contains not only paths from the CDF but also the missing parents (implicitly defined
+ * catalogs). This is why a leaf catalog was deleted. */
+ std::vector<AssetCatalogPath> expected_paths{
+ "character",
+ "character/Ellie",
+ "character/Ellie/poselib",
+ "character/Ellie/poselib/tailslash",
+ "character/Ellie/poselib/white space",
+ "character/Ružena",
+ "path",
+ "path/without",
+ "path/without/simplename",
+ };
+
+ AssetCatalogTree *tree = service.get_catalog_tree();
+ assert_expected_tree_items(tree, expected_paths);
+}
+
TEST_F(AssetCatalogTest, delete_catalog_write_to_disk)
{
TestableAssetCatalogService service(asset_library_root_);
service.load_from_disk(asset_library_root_ + "/" +
AssetCatalogService::DEFAULT_CATALOG_FILENAME);
- service.delete_catalog(UUID_POSES_ELLIE);
+ service.delete_catalog_by_id(UUID_POSES_ELLIE);
const CatalogFilePath save_to_path = use_temp_path();
AssetCatalogDefinitionFile *cdf = service.get_catalog_definition_file();
@@ -844,7 +896,7 @@ TEST_F(AssetCatalogTest, backups)
/* Read a CDF, modify, and write it. */
AssetCatalogService service(cdf_dir);
service.load_from_disk();
- service.delete_catalog(UUID_POSES_ELLIE);
+ service.delete_catalog_by_id(UUID_POSES_ELLIE);
service.write_to_disk_on_blendfile_save(cdf_dir + "phony.blend");
const CatalogFilePath backup_path = writable_cdf_file + "~";
diff --git a/source/blender/editors/asset/intern/asset_catalog.cc b/source/blender/editors/asset/intern/asset_catalog.cc
index 6e49ca2dd5c..eb1865ee9cc 100644
--- a/source/blender/editors/asset/intern/asset_catalog.cc
+++ b/source/blender/editors/asset/intern/asset_catalog.cc
@@ -77,5 +77,5 @@ void ED_asset_catalog_remove(::AssetLibrary *library, const CatalogID &catalog_i
return;
}
- catalog_service->delete_catalog(catalog_id);
+ catalog_service->prune_catalogs_by_id(catalog_id);
}