diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index 1a558c4e322..7df6e6d9f51 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -34,7 +34,9 @@ class AssetStorage; * to also include asset indexes and more. */ class AssetLibrary { - bCallbackFuncStore on_save_callback_store_{}; + /** If this is an asset library on disk, the top-level directory path. Normalized using + * #normalize_directory_path().*/ + std::string root_path_; /** Storage for assets (better said their representations) that are considered to be part of this * library. Assets are not automatically loaded into this when loading an asset library. Assets @@ -51,6 +53,8 @@ class AssetLibrary { */ std::unique_ptr asset_storage_; + bCallbackFuncStore on_save_callback_store_{}; + public: /* Controlled by #ED_asset_catalogs_set_save_catalogs_when_file_is_saved, * for managing the "Save Catalog Changes" in the quit-confirmation dialog box. */ @@ -59,10 +63,13 @@ class AssetLibrary { std::unique_ptr catalog_service; public: - AssetLibrary(); + /** + * \param root_path: If this is an asset library on disk, the top-level directory path. + */ + AssetLibrary(StringRef root_path = ""); ~AssetLibrary(); - void load_catalogs(StringRefNull library_root_directory); + void load_catalogs(); /** Load catalogs that have changed on disk. */ void refresh(); @@ -105,6 +112,8 @@ class AssetLibrary { void on_blend_save_post(Main *bmain, PointerRNA **pointers, int num_pointers); + StringRefNull root_path() const; + private: std::optional find_asset_index(const AssetRepresentation &asset); }; diff --git a/source/blender/asset_system/CMakeLists.txt b/source/blender/asset_system/CMakeLists.txt index d00c3c72e3b..c9ef11d33f4 100644 --- a/source/blender/asset_system/CMakeLists.txt +++ b/source/blender/asset_system/CMakeLists.txt @@ -21,6 +21,7 @@ set(SRC intern/asset_library_service.cc intern/asset_representation.cc intern/asset_storage.cc + intern/utils.cc AS_asset_catalog.hh AS_asset_catalog_path.hh @@ -29,6 +30,7 @@ set(SRC AS_asset_representation.hh intern/asset_library_service.hh intern/asset_storage.hh + intern/utils.hh AS_asset_library.h AS_asset_representation.h diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index 45196a218aa..7bdffe9abad 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -22,6 +22,7 @@ #include "asset_library_service.hh" #include "asset_storage.hh" +#include "utils.hh" using namespace blender; using namespace blender::asset_system; @@ -120,8 +121,9 @@ void AS_asset_library_remap_ids(const IDRemapper *mappings) namespace blender::asset_system { -AssetLibrary::AssetLibrary() - : asset_storage_(std::make_unique()), +AssetLibrary::AssetLibrary(StringRef root_path) + : root_path_(utils::normalize_directory_path(root_path)), + asset_storage_(std::make_unique()), catalog_service(std::make_unique()) { } @@ -133,9 +135,9 @@ AssetLibrary::~AssetLibrary() } } -void AssetLibrary::load_catalogs(StringRefNull library_root_directory) +void AssetLibrary::load_catalogs() { - auto catalog_service = std::make_unique(library_root_directory); + auto catalog_service = std::make_unique(root_path()); catalog_service->load_from_disk(); this->catalog_service = std::move(catalog_service); } @@ -224,6 +226,11 @@ void AssetLibrary::refresh_catalog_simplename(struct AssetMetaData *asset_data) STRNCPY(asset_data->catalog_simple_name, catalog->simple_name.c_str()); } +StringRefNull AssetLibrary::root_path() const +{ + return root_path_; +} + Vector all_valid_asset_library_refs() { Vector result; diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index 9bd2eecd468..37136968946 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -4,9 +4,6 @@ * \ingroup asset_system */ -#include "asset_library_service.hh" -#include "AS_asset_library.hh" - #include "BKE_blender.h" #include "BKE_preferences.h" @@ -19,6 +16,10 @@ #include "CLG_log.h" +#include "AS_asset_library.hh" +#include "asset_library_service.hh" +#include "utils.hh" + /* When enabled, use a pre file load handler (#BKE_CB_EVT_LOAD_PRE) callback to destroy the asset * library service. Without this an explicit call from the file loading code is needed to do this, * which is not as nice. @@ -80,41 +81,30 @@ AssetLibrary *AssetLibraryService::get_asset_library( return nullptr; } -namespace { -std::string normalize_directory_path(StringRefNull directory) +AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull root_path) { - - char dir_normalized[PATH_MAX]; - STRNCPY(dir_normalized, directory.c_str()); - BLI_path_normalize_dir(nullptr, dir_normalized, sizeof(dir_normalized)); - return std::string(dir_normalized); -} -} // namespace - -AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull top_level_directory) -{ - BLI_assert_msg(!top_level_directory.is_empty(), + BLI_assert_msg(!root_path.is_empty(), "top level directory must be given for on-disk asset library"); - std::string top_dir_trailing_slash = normalize_directory_path(top_level_directory); + std::string normalized_root_path = utils::normalize_directory_path(root_path); std::unique_ptr *lib_uptr_ptr = on_disk_libraries_.lookup_ptr( - top_dir_trailing_slash); + normalized_root_path); if (lib_uptr_ptr != nullptr) { - CLOG_INFO(&LOG, 2, "get \"%s\" (cached)", top_dir_trailing_slash.c_str()); + CLOG_INFO(&LOG, 2, "get \"%s\" (cached)", normalized_root_path.c_str()); AssetLibrary *lib = lib_uptr_ptr->get(); lib->refresh(); return lib; } - std::unique_ptr lib_uptr = std::make_unique(); + std::unique_ptr lib_uptr = std::make_unique(normalized_root_path); AssetLibrary *lib = lib_uptr.get(); lib->on_blend_save_handler_register(); - lib->load_catalogs(top_dir_trailing_slash); + lib->load_catalogs(); - on_disk_libraries_.add_new(top_dir_trailing_slash, std::move(lib_uptr)); - CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", top_dir_trailing_slash.c_str()); + on_disk_libraries_.add_new(normalized_root_path, std::move(lib_uptr)); + CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", normalized_root_path.c_str()); return lib; } diff --git a/source/blender/asset_system/intern/asset_library_service.hh b/source/blender/asset_system/intern/asset_library_service.hh index 6045060e91e..fd7d4f25d56 100644 --- a/source/blender/asset_system/intern/asset_library_service.hh +++ b/source/blender/asset_system/intern/asset_library_service.hh @@ -33,7 +33,8 @@ namespace blender::asset_system { class AssetLibraryService { static std::unique_ptr instance_; - /* Mapping absolute path of the library's top-level directory to the AssetLibrary instance. */ + /* Mapping absolute path of the library's root path (normalize with #normalize_directory_path()!) + * the AssetLibrary instance. */ Map> on_disk_libraries_; /** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If * the file was saved, a valid path for the library can be determined and #on_disk_libraries_ diff --git a/source/blender/asset_system/intern/utils.cc b/source/blender/asset_system/intern/utils.cc new file mode 100644 index 00000000000..b1e9793634d --- /dev/null +++ b/source/blender/asset_system/intern/utils.cc @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup asset_system + */ + +#include "BLI_fileops.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "utils.hh" + +namespace blender::asset_system::utils { + +std::string normalize_directory_path(StringRef directory) +{ + if (directory.is_empty()) { + return ""; + } + + char dir_normalized[PATH_MAX]; + BLI_strncpy(dir_normalized, + directory.data(), + /* + 1 for null terminator. */ + std::min(directory.size() + 1, int64_t(sizeof(dir_normalized)))); + BLI_path_normalize_dir(nullptr, dir_normalized, sizeof(dir_normalized)); + return std::string(dir_normalized); +} + +} // namespace blender::asset_system::utils diff --git a/source/blender/asset_system/intern/utils.hh b/source/blender/asset_system/intern/utils.hh new file mode 100644 index 00000000000..cccc24984ba --- /dev/null +++ b/source/blender/asset_system/intern/utils.hh @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup asset_system + */ + +#pragma once + +#include "BLI_string_ref.hh" + +namespace blender::asset_system::utils { + +/** + * Returns a normalized directory path with a trailing slash, and a maximum length of #PATH_MAX. + * Slashes are not converted to native format (they probably should be though?). + */ +std::string normalize_directory_path(StringRef directory); + +} // namespace blender::asset_system::utils