diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/asset_catalog.cc | 41 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/asset_catalog_test.cc | 48 |
2 files changed, 89 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc index 8f57f96e771..05e27a93621 100644 --- a/source/blender/blenkernel/intern/asset_catalog.cc +++ b/source/blender/blenkernel/intern/asset_catalog.cc @@ -99,6 +99,25 @@ void AssetCatalogService::delete_catalog(CatalogID catalog_id) this->rebuild_tree(); } +void AssetCatalogService::update_catalog_path(CatalogID catalog_id, + const CatalogPath &new_catalog_path) +{ + AssetCatalog *renamed_cat = this->find_catalog(catalog_id); + const CatalogPath old_cat_path = renamed_cat->path; + + for (auto &catalog_uptr : catalogs_.values()) { + AssetCatalog *cat = catalog_uptr.get(); + if (!cat->is_contained_in(old_cat_path)) { + continue; + } + + const CatalogPath path_suffix = cat->path.substr(old_cat_path.length()); + cat->path = new_catalog_path + path_suffix; + } + + this->rebuild_tree(); +} + AssetCatalog *AssetCatalogService::create_catalog(const CatalogPath &catalog_path) { std::unique_ptr<AssetCatalog> catalog = AssetCatalog::from_path(catalog_path); @@ -756,4 +775,26 @@ CatalogPath AssetCatalog::cleanup_path(const CatalogPath &path) return clean_path; } +bool AssetCatalog::is_contained_in(const CatalogPath &other_path) const +{ + if (other_path.empty()) { + return true; + } + + if (this->path == other_path) { + return true; + } + + /* To be a child path of 'other_path', our path must be at least a separator and another + * character longer. */ + if (this->path.length() < other_path.length() + 2) { + return false; + } + + const StringRef this_path(this->path); + const bool prefix_ok = this_path.startswith(other_path); + const char next_char = this_path[other_path.length()]; + return prefix_ok && next_char == AssetCatalogService::PATH_SEPARATOR; +} + } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/asset_catalog_test.cc b/source/blender/blenkernel/intern/asset_catalog_test.cc index 5177abd2820..b36c15940b8 100644 --- a/source/blender/blenkernel/intern/asset_catalog_test.cc +++ b/source/blender/blenkernel/intern/asset_catalog_test.cc @@ -711,6 +711,37 @@ TEST_F(AssetCatalogTest, delete_catalog_write_to_disk) EXPECT_NE(nullptr, loaded_service.find_catalog(UUID_POSES_RUZENA_FACE)); } +TEST_F(AssetCatalogTest, update_catalog_path) +{ + AssetCatalogService service(asset_library_root_); + service.load_from_disk(asset_library_root_ + "/" + + AssetCatalogService::DEFAULT_CATALOG_FILENAME); + + const AssetCatalog *orig_cat = service.find_catalog(UUID_POSES_RUZENA); + const CatalogPath orig_path = orig_cat->path; + + service.update_catalog_path(UUID_POSES_RUZENA, "charlib/Ružena"); + + EXPECT_EQ(nullptr, service.find_catalog_by_path(orig_path)) + << "The original (pre-rename) path should not be associated with a catalog any more."; + + const AssetCatalog *renamed_cat = service.find_catalog(UUID_POSES_RUZENA); + ASSERT_NE(nullptr, renamed_cat); + ASSERT_EQ(orig_cat, renamed_cat) << "Changing the path should not reallocate the catalog."; + EXPECT_EQ(orig_cat->simple_name, renamed_cat->simple_name) + << "Changing the path should not change the simple name."; + EXPECT_EQ(orig_cat->catalog_id, renamed_cat->catalog_id) + << "Changing the path should not change the catalog ID."; + + EXPECT_EQ("charlib/Ružena", renamed_cat->path) + << "Changing the path should change the path. Surprise."; + + EXPECT_EQ("charlib/Ružena/hand", service.find_catalog(UUID_POSES_RUZENA_HAND)->path) + << "Changing the path should update children."; + EXPECT_EQ("charlib/Ružena/face", service.find_catalog(UUID_POSES_RUZENA_FACE)->path) + << "Changing the path should update children."; +} + TEST_F(AssetCatalogTest, merge_catalog_files) { const CatalogFilePath cdf_dir = create_temp_path(); @@ -813,4 +844,21 @@ TEST_F(AssetCatalogTest, order_by_path) } } +TEST_F(AssetCatalogTest, is_contained_in) +{ + const AssetCatalog cat(BLI_uuid_generate_random(), "simple/path/child", ""); + + EXPECT_FALSE(cat.is_contained_in("unrelated")); + EXPECT_FALSE(cat.is_contained_in("sim")); + EXPECT_FALSE(cat.is_contained_in("simple/pathx")); + EXPECT_FALSE(cat.is_contained_in("simple/path/c")); + EXPECT_FALSE(cat.is_contained_in("simple/path/child/grandchild")); + EXPECT_FALSE(cat.is_contained_in("simple/path/")) + << "Non-normalized paths are not expected to work."; + + EXPECT_TRUE(cat.is_contained_in("")); + EXPECT_TRUE(cat.is_contained_in("simple")); + EXPECT_TRUE(cat.is_contained_in("simple/path")); +} + } // namespace blender::bke::tests |