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:
authorSybren A. Stüvel <sybren@blender.org>2021-10-18 13:33:53 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-10-18 15:21:41 +0300
commitf9113c4be836691ba599aab9b2f43e26333f8133 (patch)
tree6fa8fc9c1021538478f173e247d932c63929f15b /source/blender/blenkernel/intern/asset_library_service.cc
parent1f510376764debe3e91f736aec6b3af70567243f (diff)
Assets: add global `bke::AssetLibraryService` class
Add `blender::bke::AssetLibraryService` class that acts like a blendfile-scoped singleton. It's allocated upon the first call to `BKE_asset_library_load` and destroyed in the LOAD-PRE handler. The `AssetLibraryService` ensures that edits to asset catalogs are not lost when the asset browser editor closes (or even reloads). Instead, the `AssetLibrary` pointers it owns are kept around as long as the blend file is open. Reviewed By: Severin Maniphest Tasks: T92151 Differential Revision: https://developer.blender.org/D12885
Diffstat (limited to 'source/blender/blenkernel/intern/asset_library_service.cc')
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.cc136
1 files changed, 136 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/asset_library_service.cc b/source/blender/blenkernel/intern/asset_library_service.cc
new file mode 100644
index 00000000000..14604def0d3
--- /dev/null
+++ b/source/blender/blenkernel/intern/asset_library_service.cc
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "asset_library_service.hh"
+
+#include "BKE_asset_library.hh"
+#include "BKE_blender.h"
+#include "BKE_callbacks.h"
+
+#include "BLI_string_ref.hh"
+
+#include "MEM_guardedalloc.h"
+
+#include "CLG_log.h"
+
+static CLG_LogRef LOG = {"bke.asset_service"};
+
+namespace blender::bke {
+
+std::unique_ptr<AssetLibraryService> AssetLibraryService::instance_;
+bool AssetLibraryService::atexit_handler_registered_ = false;
+
+AssetLibraryService *AssetLibraryService::get()
+{
+ if (!instance_) {
+ allocate_service_instance();
+ }
+ return instance_.get();
+}
+
+void AssetLibraryService::destroy()
+{
+ if (!instance_) {
+ return;
+ }
+ instance_->app_handler_unregister();
+ instance_.reset();
+}
+
+AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull top_level_directory)
+{
+ BLI_assert_msg(!top_level_directory.is_empty(),
+ "top level directory must be given for on-disk asset library");
+
+ AssetLibraryPtr *lib_uptr_ptr = on_disk_libraries_.lookup_ptr(top_level_directory);
+ if (lib_uptr_ptr != nullptr) {
+ CLOG_INFO(&LOG, 2, "get \"%s\" (cached)", top_level_directory.c_str());
+ return lib_uptr_ptr->get();
+ }
+
+ AssetLibraryPtr lib_uptr = std::make_unique<AssetLibrary>();
+ AssetLibrary *lib = lib_uptr.get();
+
+ lib->on_save_handler_register();
+ lib->load(top_level_directory);
+
+ on_disk_libraries_.add_new(top_level_directory, std::move(lib_uptr));
+ CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", top_level_directory.c_str());
+ return lib;
+}
+
+AssetLibrary *AssetLibraryService::get_asset_library_current_file()
+{
+ if (current_file_library_) {
+ CLOG_INFO(&LOG, 2, "get current file lib (cached)");
+ }
+ else {
+ CLOG_INFO(&LOG, 2, "get current file lib (loaded)");
+ current_file_library_ = std::make_unique<AssetLibrary>();
+ current_file_library_->on_save_handler_register();
+ }
+
+ AssetLibrary *lib = current_file_library_.get();
+ return lib;
+}
+
+void AssetLibraryService::allocate_service_instance()
+{
+ instance_ = std::make_unique<AssetLibraryService>();
+ instance_->app_handler_register();
+
+ if (!atexit_handler_registered_) {
+ /* Ensure the instance gets freed before Blender's memory leak detector runs. */
+ BKE_blender_atexit_register([](void * /*user_data*/) { AssetLibraryService::destroy(); },
+ nullptr);
+ atexit_handler_registered_ = true;
+ }
+}
+
+static void on_blendfile_load(struct Main * /*bMain*/,
+ struct PointerRNA ** /*pointers*/,
+ const int /*num_pointers*/,
+ void * /*arg*/)
+{
+ AssetLibraryService::destroy();
+}
+
+/**
+ * Ensure the AssetLibraryService instance is destroyed before a new blend file is loaded.
+ * This makes memory management simple, and ensures a fresh start for every blend file. */
+void AssetLibraryService::app_handler_register()
+{
+ /* The callback system doesn't own `on_load_callback_store_`. */
+ on_load_callback_store_.alloc = false;
+
+ on_load_callback_store_.func = &on_blendfile_load;
+ on_load_callback_store_.arg = this;
+
+ BKE_callback_add(&on_load_callback_store_, BKE_CB_EVT_LOAD_PRE);
+}
+
+void AssetLibraryService::app_handler_unregister()
+{
+ BKE_callback_remove(&on_load_callback_store_, BKE_CB_EVT_LOAD_PRE);
+ on_load_callback_store_.func = nullptr;
+ on_load_callback_store_.arg = nullptr;
+}
+
+} // namespace blender::bke