Files
test2/source/blender/asset_system/intern/asset_representation.cc
Julian Eisel 21e626ced3 Refactor: Assets: Improve asset system APIs for asset operators
Brush and pose asset operators were doing some avoidable roundtrips
through asset types, lookups and rather low level operations. This
indicates that the asset system APIs need some improvements. Moving
lower-level logic there can help avoiding errors, since implementation
details are kept inside the corresponding module.

- Avoid lookups for asset library reference in operator code, make asset
  library itself construct it.
- Avoid redundant lookups for asset library definition (was looking up
  the asset library definition in the Preferences from the library
  reference type, just to turn it into the reference type again).
- Add utility for refreshing loading asset libraries
- Add utility for saving asset catalogs for an asset
- Remove unused function
2025-02-04 17:28:23 +01:00

177 lines
4.6 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#include <stdexcept>
#include "BLI_path_utils.hh"
#include "BKE_blendfile.hh"
#include "BKE_icons.h"
#include "BKE_preview_image.hh"
#include "DNA_ID.h"
#include "DNA_asset_types.h"
#include "IMB_thumbs.hh"
#include "AS_asset_library.hh"
#include "AS_asset_representation.hh"
namespace blender::asset_system {
AssetRepresentation::AssetRepresentation(StringRef relative_asset_path,
StringRef name,
const int id_type,
std::unique_ptr<AssetMetaData> metadata,
AssetLibrary &owner_asset_library)
: owner_asset_library_(owner_asset_library),
relative_identifier_(relative_asset_path),
asset_(AssetRepresentation::ExternalAsset{name, id_type, std::move(metadata), nullptr})
{
}
AssetRepresentation::AssetRepresentation(StringRef relative_asset_path,
ID &id,
AssetLibrary &owner_asset_library)
: owner_asset_library_(owner_asset_library),
relative_identifier_(relative_asset_path),
asset_(&id)
{
if (!id.asset_data) {
throw std::invalid_argument("Passed ID is not an asset");
}
}
AssetRepresentation::~AssetRepresentation()
{
if (const ExternalAsset *extern_asset = std::get_if<ExternalAsset>(&asset_);
extern_asset && extern_asset->preview_)
{
BKE_previewimg_cached_release(this->full_path().c_str());
}
}
AssetWeakReference AssetRepresentation::make_weak_reference() const
{
return AssetWeakReference::make_reference(owner_asset_library_, relative_identifier_);
}
void AssetRepresentation::ensure_previewable()
{
if (ID *id = this->local_id()) {
PreviewImage *preview = BKE_previewimg_id_ensure(id);
BKE_icon_preview_ensure(id, preview);
return;
}
ExternalAsset &extern_asset = std::get<ExternalAsset>(asset_);
/* Use the full path as preview name, it's the only unique identifier we have. */
const std::string full_path = this->full_path();
/* Doesn't do the actual reading, just allocates and attaches the derived load info. */
extern_asset.preview_ = BKE_previewimg_cached_thumbnail_read(
full_path.c_str(), full_path.c_str(), THB_SOURCE_BLEND, false);
BKE_icon_preview_ensure(nullptr, extern_asset.preview_);
}
PreviewImage *AssetRepresentation::get_preview() const
{
if (const ID *id = this->local_id()) {
return BKE_previewimg_id_get(id);
}
return std::get<ExternalAsset>(asset_).preview_;
}
StringRefNull AssetRepresentation::get_name() const
{
if (const ID *id = this->local_id()) {
return id->name + 2;
}
return std::get<ExternalAsset>(asset_).name;
}
ID_Type AssetRepresentation::get_id_type() const
{
if (const ID *id = this->local_id()) {
return GS(id->name);
}
return ID_Type(std::get<ExternalAsset>(asset_).id_type);
}
AssetMetaData &AssetRepresentation::get_metadata() const
{
if (const ID *id = this->local_id()) {
return *id->asset_data;
}
return *std::get<ExternalAsset>(asset_).metadata_;
}
StringRefNull AssetRepresentation::library_relative_identifier() const
{
return relative_identifier_;
}
std::string AssetRepresentation::full_path() const
{
char filepath[FILE_MAX];
BLI_path_join(filepath,
sizeof(filepath),
owner_asset_library_.root_path().c_str(),
relative_identifier_.c_str());
return filepath;
}
std::string AssetRepresentation::full_library_path() const
{
std::string asset_path = full_path();
char blend_path[1090 /*FILE_MAX_LIBEXTRA*/];
if (!BKE_blendfile_library_path_explode(asset_path.c_str(), blend_path, nullptr, nullptr)) {
return {};
}
return blend_path;
}
std::optional<eAssetImportMethod> AssetRepresentation::get_import_method() const
{
return owner_asset_library_.import_method_;
}
bool AssetRepresentation::may_override_import_method() const
{
if (!owner_asset_library_.import_method_) {
return true;
}
return owner_asset_library_.may_override_import_method_;
}
bool AssetRepresentation::get_use_relative_path() const
{
return owner_asset_library_.use_relative_path_;
}
ID *AssetRepresentation::local_id() const
{
return this->is_local_id() ? std::get<ID *>(asset_) : nullptr;
}
bool AssetRepresentation::is_local_id() const
{
return std::holds_alternative<ID *>(asset_);
}
AssetLibrary &AssetRepresentation::owner_asset_library() const
{
return owner_asset_library_;
}
} // namespace blender::asset_system