Assets: add function to copy asset data to another ID #108547
|
@ -38,6 +38,13 @@ typedef struct AssetTypeInfo {
|
|||
struct AssetMetaData *BKE_asset_metadata_create(void);
|
||||
void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
|
||||
|
||||
/**
|
||||
* Create a copy of the #AssetMetaData so that it can be assigned to another asset.
|
||||
*
|
||||
* The caller becomes the owner of the returned pointer.
|
||||
*/
|
||||
struct AssetMetaData *BKE_asset_metadata_copy(const struct AssetMetaData *source);
|
||||
|
||||
struct AssetTagEnsureResult {
|
||||
struct AssetTag *tag;
|
||||
/* Set to false if a tag of this name was already present. */
|
||||
|
|
|
@ -39,6 +39,38 @@ void BKE_asset_metadata_free(AssetMetaData **asset_data)
|
|||
*asset_data = nullptr;
|
||||
}
|
||||
|
||||
AssetMetaData *BKE_asset_metadata_copy(const AssetMetaData *source)
|
||||
{
|
||||
AssetMetaData *copy = BKE_asset_metadata_create();
|
||||
|
||||
copy->local_type_info = source->local_type_info;
|
||||
|
||||
if (source->properties) {
|
||||
copy->properties = IDP_CopyProperty(source->properties);
|
||||
}
|
||||
|
||||
BKE_asset_metadata_catalog_id_set(copy, source->catalog_id, source->catalog_simple_name);
|
||||
|
||||
if (source->author) {
|
||||
copy->author = BLI_strdup(source->author);
|
||||
}
|
||||
if (source->description) {
|
||||
copy->description = BLI_strdup(source->description);
|
||||
}
|
||||
if (source->copyright) {
|
||||
copy->copyright = BLI_strdup(source->copyright);
|
||||
}
|
||||
if (source->license) {
|
||||
copy->license = BLI_strdup(source->license);
|
||||
}
|
||||
|
||||
BLI_duplicatelist(©->tags, &source->tags);
|
||||
copy->active_tag = source->active_tag;
|
||||
copy->tot_tags = source->tot_tags;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
AssetMetaData::~AssetMetaData()
|
||||
{
|
||||
if (properties) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct AssetMetaData;
|
||||
struct ID;
|
||||
struct Main;
|
||||
struct bContext;
|
||||
|
@ -42,6 +43,18 @@ void ED_asset_generate_preview(const struct bContext *C, struct ID *id);
|
|||
*/
|
||||
bool ED_asset_clear_id(struct ID *id);
|
||||
|
||||
/**
|
||||
* Copy the asset metadata to the given destination ID.
|
||||
*
|
||||
* The copy is assigned to \a destination, any pre-existing asset metadata is
|
||||
* freed before that. If \a destination was not yet marked as asset, it will be
|
||||
* after this call.
|
||||
*
|
||||
* \return true when the copy succeeded, false otherwise. The only reason for
|
||||
* failure is when \a destination is of a type that cannot be an asset.
|
||||
*/
|
||||
bool ED_asset_copy_to_id(const struct AssetMetaData *asset_data, struct ID *destination);
|
||||
|
||||
void ED_assets_pre_save(struct Main *bmain);
|
||||
|
||||
bool ED_asset_can_mark_single_from_context(const struct bContext *C);
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include "ED_asset_mark_clear.h"
|
||||
#include "ED_asset_type.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
bool ED_asset_mark_id(ID *id)
|
||||
{
|
||||
if (id->asset_data) {
|
||||
|
@ -96,3 +99,16 @@ bool ED_asset_can_mark_single_from_context(const bContext *C)
|
|||
}
|
||||
return ED_asset_type_is_supported(id);
|
||||
}
|
||||
|
||||
bool ED_asset_copy_to_id(const struct AssetMetaData *asset_data, struct ID *destination)
|
||||
{
|
||||
if (!BKE_id_can_be_asset(destination)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destination->asset_data) {
|
||||
BKE_asset_metadata_free(&destination->asset_data);
|
||||
}
|
||||
destination->asset_data = BKE_asset_metadata_copy(asset_data);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -725,6 +725,38 @@ static void rna_ID_asset_clear(ID *id)
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_ID_asset_data_set(PointerRNA *ptr, PointerRNA value, struct ReportList *reports)
|
||||
{
|
||||
ID *destination = ptr->data;
|
||||
|
||||
/* Avoid marking as asset by assigning. This should be done wiht .asset_mark(). This is just for
|
||||
* clarity of the API, and to accomodate future changes. */
|
||||
if (destination->asset_data == NULL) {
|
||||
BKE_report(reports,
|
||||
RPT_ERROR,
|
||||
"Asset data can only be assigned to assets. Use asset_mark() to mark as an asset");
|
||||
return;
|
||||
}
|
||||
|
||||
const AssetMetaData *asset_data = value.data;
|
||||
if (asset_data == NULL) {
|
||||
/* Avoid clearing the asset data on assets. Un-marking as asset should be done with
|
||||
* .asset_clear(). This is just for clarity of the API, and to accomodate future changes. */
|
||||
BKE_report(reports, RPT_ERROR, "Asset data cannot be None");
|
||||
return;
|
||||
}
|
||||
|
||||
const bool assigned_ok = ED_asset_copy_to_id(asset_data, destination);
|
||||
if (!assigned_ok) {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "'%s' is of a type that cannot be an asset", destination->name + 2);
|
||||
return;
|
||||
}
|
||||
|
||||
WM_main_add_notifier(NC_ASSET | NA_EDITED, NULL);
|
||||
WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static ID *rna_ID_override_create(ID *id, Main *bmain, bool remap_local_usages)
|
||||
{
|
||||
if (!ID_IS_OVERRIDABLE_LIBRARY(id)) {
|
||||
|
@ -2131,7 +2163,8 @@ static void rna_def_ID(BlenderRNA *brna)
|
|||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
|
||||
prop = RNA_def_property(srna, "asset_data", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_ID_asset_data_set", NULL, NULL);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
RNA_def_property_ui_text(prop, "Asset Data", "Additional data for an asset data-block");
|
||||
|
||||
|
|
Loading…
Reference in New Issue