[Bf-blender-cvs] [c6db534b996] temp-asset-browser-catalogs-ui: Ensure unique catalog name when adding
Julian Eisel
noreply at git.blender.org
Tue Sep 21 00:18:01 CEST 2021
Commit: c6db534b996993b5f75f2b3bb7b9846f41ca7f50
Author: Julian Eisel
Date: Tue Sep 21 00:16:30 2021 +0200
Branches: temp-asset-browser-catalogs-ui
https://developer.blender.org/rBc6db534b996993b5f75f2b3bb7b9846f41ca7f50
Ensure unique catalog name when adding
Without this, adding multiple catalogs would always add them with the
same name. The first duplicate name would cause an assert to fail.
===================================================================
M source/blender/blenkernel/BKE_asset_catalog.hh
M source/blender/blenkernel/intern/asset_catalog.cc
M source/blender/editors/asset/ED_asset_catalog.hh
M source/blender/editors/asset/intern/asset_catalog.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_asset_catalog.hh b/source/blender/blenkernel/BKE_asset_catalog.hh
index 77195b010d8..d283de9af2f 100644
--- a/source/blender/blenkernel/BKE_asset_catalog.hh
+++ b/source/blender/blenkernel/BKE_asset_catalog.hh
@@ -64,6 +64,10 @@ class AssetCatalogService {
/** Return catalog with the given ID. Return nullptr if not found. */
AssetCatalog *find_catalog(const CatalogID &catalog_id);
+ /** Return first catalog with the given path. Return nullptr if not found. Not the most efficient
+ * function, better don't use it in performance sensitive areas. */
+ AssetCatalog *find_catalog_from_path(const CatalogPath &path) const;
+
/** Create a catalog with some sensible auto-generated catalog ID.
* The catalog will be saved to the default catalog file.*/
AssetCatalog *create_catalog(const CatalogPath &catalog_path);
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index 22da9b25235..53bfaf05206 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -52,6 +52,17 @@ AssetCatalog *AssetCatalogService::find_catalog(const CatalogID &catalog_id)
return catalog_uptr_ptr->get();
}
+AssetCatalog *AssetCatalogService::find_catalog_from_path(const CatalogPath &path) const
+{
+ for (auto &catalog : catalogs_.values()) {
+ if (catalog->path == path) {
+ return catalog.get();
+ }
+ }
+
+ return nullptr;
+}
+
AssetCatalog *AssetCatalogService::create_catalog(const CatalogPath &catalog_path)
{
std::unique_ptr<AssetCatalog> catalog = AssetCatalog::from_path(catalog_path);
@@ -59,6 +70,8 @@ AssetCatalog *AssetCatalogService::create_catalog(const CatalogPath &catalog_pat
/* So we can std::move(catalog) and still use the non-owning pointer: */
AssetCatalog *const catalog_ptr = catalog.get();
+ BLI_assert_msg(find_catalog_from_path(catalog_path) == nullptr,
+ "duplicate catalog path not supported");
/* TODO(@sybren): move the `AssetCatalog::from_path()` function to another place, that can reuse
* catalogs when a catalog with the given path is already known, and avoid duplicate catalog IDs.
*/
diff --git a/source/blender/editors/asset/ED_asset_catalog.hh b/source/blender/editors/asset/ED_asset_catalog.hh
index c08fa9ad093..7ed12c76214 100644
--- a/source/blender/editors/asset/ED_asset_catalog.hh
+++ b/source/blender/editors/asset/ED_asset_catalog.hh
@@ -28,5 +28,5 @@ struct AssetLibrary;
} // namespace blender::bke
blender::bke::AssetCatalog *ED_asset_catalog_add(blender::bke::AssetLibrary *library,
- blender::StringRef name,
+ blender::StringRefNull name,
blender::StringRef parent_path = nullptr);
diff --git a/source/blender/editors/asset/intern/asset_catalog.cc b/source/blender/editors/asset/intern/asset_catalog.cc
index bc03d3c5263..b1a38e67e97 100644
--- a/source/blender/editors/asset/intern/asset_catalog.cc
+++ b/source/blender/editors/asset/intern/asset_catalog.cc
@@ -21,17 +21,63 @@
#include "BKE_asset_catalog.hh"
#include "BKE_asset_library.hh"
+#include "BLI_string_utils.h"
+
#include "ED_asset_catalog.hh"
using namespace blender;
using namespace blender::bke;
+struct CatalogUniqueNameFnData {
+ const AssetCatalogService &catalog_service;
+ StringRef parent_path;
+};
+
+static std::string to_full_path(StringRef parent_path, StringRef name)
+{
+ return parent_path.is_empty() ?
+ std::string(name) :
+ std::string(parent_path) + AssetCatalogService::PATH_SEPARATOR + name;
+}
+
+static bool catalog_name_is_not_unique_fn(void *arg, const char *name)
+{
+ CatalogUniqueNameFnData &fn_data = *static_cast<CatalogUniqueNameFnData *>(arg);
+ std::string fullpath = to_full_path(fn_data.parent_path, name);
+ if (fn_data.catalog_service.find_catalog_from_path(fullpath)) {
+ return true;
+ }
+ return false;
+}
+
+static std::string catalog_name_ensure_unique(AssetCatalogService &catalog_service,
+ StringRefNull name,
+ StringRef parent_path)
+{
+ CatalogUniqueNameFnData fn_data = {catalog_service, parent_path};
+
+ char unique_name[NAME_MAX] = "";
+ BLI_uniquename_cb(catalog_name_is_not_unique_fn,
+ &fn_data,
+ name.c_str(),
+ '.',
+ unique_name,
+ sizeof(unique_name));
+
+ return unique_name;
+}
+
AssetCatalog *ED_asset_catalog_add(blender::bke::AssetLibrary *library,
- StringRef name,
+ StringRefNull name,
StringRef parent_path)
{
- std::string fullpath = parent_path.is_empty() ?
- std::string(name) :
- std::string(parent_path) + AssetCatalogService::PATH_SEPARATOR + name;
+ if (!library || !library->catalog_service) {
+ return nullptr;
+ }
+
+ std::string unique_name = catalog_name_ensure_unique(
+ *library->catalog_service, name, parent_path);
+ std::string fullpath = to_full_path(parent_path, unique_name);
+
return library->catalog_service->create_catalog(fullpath);
}
More information about the Bf-blender-cvs
mailing list