From 637731dc610370782b1041ece4425bf3e6086ba0 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 8 Jul 2021 16:27:18 +0200 Subject: Assets: Abstraction for temporary loading of asset data-blocks This is an editor-level abstraction for the `BLO_library_temp_xxx()` API for temporary loading of data-blocks from another Blend file. It abstracts away the asset specific code, like asset file-path handling and local asset data-block handling. Main use-case for this is applying assets as presets that are based on data-blocks, like poses. Such preset assets are an important part of the asset system design, so such an abstraction will likely find more usage in the future. --- source/blender/editors/asset/CMakeLists.txt | 1 + .../editors/asset/asset_temp_id_consumer.cc | 113 +++++++++++++++++++++ source/blender/editors/include/ED_asset.h | 11 ++ 3 files changed, 125 insertions(+) create mode 100644 source/blender/editors/asset/asset_temp_id_consumer.cc diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt index d87879bea2a..a27975bc37b 100644 --- a/source/blender/editors/asset/CMakeLists.txt +++ b/source/blender/editors/asset/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRC asset_edit.cc asset_list.cc asset_ops.cc + asset_temp_id_consumer.cc ) set(LIB diff --git a/source/blender/editors/asset/asset_temp_id_consumer.cc b/source/blender/editors/asset/asset_temp_id_consumer.cc new file mode 100644 index 00000000000..24e1fc86fef --- /dev/null +++ b/source/blender/editors/asset/asset_temp_id_consumer.cc @@ -0,0 +1,113 @@ +/* + * 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 edasset + * + * API for temporary loading of asset IDs. + * Uses the `BLO_library_temp_xxx()` API internally. + */ + +#include "DNA_asset_types.h" +#include "DNA_space_types.h" + +#include "BKE_report.h" + +#include "BLI_utility_mixins.hh" + +#include "BLO_readfile.h" + +#include "MEM_guardedalloc.h" + +#include "ED_asset.h" + +using namespace blender; + +class AssetTemporaryIDConsumer : NonCopyable, NonMovable { + const AssetHandle &handle_; + TempLibraryContext *temp_lib_context_ = nullptr; + + public: + AssetTemporaryIDConsumer(const AssetHandle &handle) : handle_(handle) + { + } + ~AssetTemporaryIDConsumer() + { + if (temp_lib_context_) { + BLO_library_temp_free(temp_lib_context_); + } + } + + ID *get_local_id() + { + return ED_assetlist_asset_local_id_get(&handle_); + } + + ID *import_id(const bContext *C, + const AssetLibraryReference &asset_library, + ID_Type id_type, + Main &bmain, + ReportList &reports) + { + const char *asset_name = ED_asset_handle_get_name(&handle_); + char blend_file_path[FILE_MAX_LIBEXTRA]; + ED_asset_handle_get_full_library_path(C, &asset_library, &handle_, blend_file_path); + + temp_lib_context_ = BLO_library_temp_load_id( + &bmain, blend_file_path, id_type, asset_name, &reports); + + if (temp_lib_context_ == nullptr || temp_lib_context_->temp_id == nullptr) { + BKE_reportf(&reports, RPT_ERROR, "Unable to load %s from %s", asset_name, blend_file_path); + return nullptr; + } + + BLI_assert(GS(temp_lib_context_->temp_id->name) == id_type); + return temp_lib_context_->temp_id; + } +}; + +AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const AssetHandle *handle) +{ + if (!handle) { + return nullptr; + } + BLI_assert(handle->file_data->asset_data != nullptr); + return reinterpret_cast( + OBJECT_GUARDED_NEW(AssetTemporaryIDConsumer, *handle)); +} + +void ED_asset_temp_id_consumer_free(AssetTempIDConsumer **consumer) +{ + OBJECT_GUARDED_SAFE_DELETE(*consumer, AssetTemporaryIDConsumer); +} + +ID *ED_asset_temp_id_consumer_ensure_local_id(AssetTempIDConsumer *consumer_, + const bContext *C, + const AssetLibraryReference *asset_library, + ID_Type id_type, + Main *bmain, + ReportList *reports) +{ + if (!(consumer_ && asset_library && bmain && reports)) { + return nullptr; + } + AssetTemporaryIDConsumer *consumer = reinterpret_cast(consumer_); + + if (ID *local_id = consumer->get_local_id()) { + return local_id; + } + return consumer->import_id(C, *asset_library, id_type, *bmain, *reports); +} diff --git a/source/blender/editors/include/ED_asset.h b/source/blender/editors/include/ED_asset.h index 381071a5c6f..d33085f1cc4 100644 --- a/source/blender/editors/include/ED_asset.h +++ b/source/blender/editors/include/ED_asset.h @@ -33,6 +33,8 @@ struct Main; struct ReportList; struct wmNotifier; +typedef struct AssetTempIDConsumer AssetTempIDConsumer; + bool ED_asset_mark_id(const struct bContext *C, struct ID *id); bool ED_asset_clear_id(struct ID *id); @@ -47,6 +49,15 @@ void ED_asset_handle_get_full_library_path(const struct bContext *C, const AssetHandle *asset, char r_full_lib_path[]); +AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const AssetHandle *handle); +void ED_asset_temp_id_consumer_free(AssetTempIDConsumer **consumer); +struct ID *ED_asset_temp_id_consumer_ensure_local_id(AssetTempIDConsumer *consumer, + const struct bContext *C, + const AssetLibraryReference *asset_library, + ID_Type id_type, + struct Main *bmain, + struct ReportList *reports); + void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference, const struct AssetFilterSettings *filter_settings, const struct bContext *C); -- cgit v1.2.3