Blender V4.3
asset.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstring>
10#include <utility>
11
12#include "DNA_ID.h"
13#include "DNA_defaults.h"
14
15#include "BLI_listbase.h"
16#include "BLI_string.h"
17#include "BLI_string_ref.hh"
18#include "BLI_string_utf8.h"
19#include "BLI_string_utils.hh"
20#include "BLI_uuid.h"
21
22#include "BKE_asset.hh"
23#include "BKE_idprop.hh"
24#include "BKE_preview_image.hh"
25
26#include "BLO_read_write.hh"
27
28#include "MEM_guardedalloc.h"
29
30using namespace blender;
31
33{
34 const AssetMetaData *default_metadata = DNA_struct_default_get(AssetMetaData);
35 return MEM_new<AssetMetaData>(__func__, *default_metadata);
36}
37
39{
40 MEM_delete(*asset_data);
41 *asset_data = nullptr;
42}
43
45{
46 return MEM_new<AssetMetaData>(__func__, *source);
47}
48
49AssetMetaData::AssetMetaData(const AssetMetaData &other)
50 : local_type_info(other.local_type_info),
51 properties(nullptr),
52 catalog_id(other.catalog_id),
53 active_tag(other.active_tag),
54 tot_tags(other.tot_tags)
55{
56 if (other.properties) {
57 properties = IDP_CopyProperty(other.properties);
58 }
59
60 STRNCPY(catalog_simple_name, other.catalog_simple_name);
61
62 author = BLI_strdup_null(other.author);
63 description = BLI_strdup_null(other.description);
64 copyright = BLI_strdup_null(other.copyright);
65 license = BLI_strdup_null(other.license);
66
67 BLI_duplicatelist(&tags, &other.tags);
68}
69
70AssetMetaData::AssetMetaData(AssetMetaData &&other)
71 : local_type_info(other.local_type_info),
72 properties(std::exchange(other.properties, nullptr)),
73 catalog_id(other.catalog_id),
74 author(std::exchange(other.author, nullptr)),
75 description(std::exchange(other.description, nullptr)),
76 copyright(std::exchange(other.copyright, nullptr)),
77 license(std::exchange(other.license, nullptr)),
78 active_tag(other.active_tag),
79 tot_tags(other.tot_tags)
80{
81 STRNCPY(catalog_simple_name, other.catalog_simple_name);
82 tags = other.tags;
83 BLI_listbase_clear(&other.tags);
84}
85
86AssetMetaData::~AssetMetaData()
87{
88 if (properties) {
90 }
96}
97
98static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
99{
100 AssetTag *tag = (AssetTag *)MEM_callocN(sizeof(*tag), __func__);
101 STRNCPY_UTF8(tag->name, name);
102
103 BLI_addtail(&asset_data->tags, tag);
104 asset_data->tot_tags++;
105 /* Invariant! */
106 BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
107
108 return tag;
109}
110
111AssetTag *BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name)
112{
113 AssetTag *tag = asset_metadata_tag_add(asset_data, name);
114 BLI_uniquename(&asset_data->tags, tag, name, '.', offsetof(AssetTag, name), sizeof(tag->name));
115 return tag;
116}
117
119{
120 AssetTagEnsureResult result = {nullptr};
121 if (!name[0]) {
122 return result;
123 }
124
125 AssetTag *tag = (AssetTag *)BLI_findstring(&asset_data->tags, name, offsetof(AssetTag, name));
126
127 if (tag) {
128 result.tag = tag;
129 result.is_new = false;
130 return result;
131 }
132
133 tag = asset_metadata_tag_add(asset_data, name);
134
135 result.tag = tag;
136 result.is_new = true;
137 return result;
138}
139
141{
142 BLI_assert(BLI_findindex(&asset_data->tags, tag) >= 0);
143 BLI_freelinkN(&asset_data->tags, tag);
144 asset_data->tot_tags--;
145 /* Invariant! */
146 BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
147}
148
150{
151 memcpy(library_ref, DNA_struct_default_get(AssetLibraryReference), sizeof(*library_ref));
152}
153
155{
156 asset_data->catalog_id = BLI_uuid_nil();
157 asset_data->catalog_simple_name[0] = '\0';
158}
159
161 const ::bUUID catalog_id,
162 const char *catalog_simple_name)
163{
164 asset_data->catalog_id = catalog_id;
165
166 constexpr size_t max_simple_name_length = sizeof(asset_data->catalog_simple_name);
167
168 /* The substr() call is necessary to make copy() copy the first N characters (instead of refusing
169 * to copy and producing an empty string). */
170 StringRef trimmed_id =
171 StringRef(catalog_simple_name).trim().substr(0, max_simple_name_length - 1);
172 trimmed_id.copy(asset_data->catalog_simple_name, max_simple_name_length);
173}
174
176{
177 using namespace blender::bke;
178 if (!asset_data->properties) {
179 asset_data->properties = idprop::create_group("AssetMetaData.properties").release();
180 }
181 /* Important: The property may already exist. For now just allow always allow a newly allocated
182 * property, and replace the existing one as a way of updating. */
183 IDP_ReplaceInGroup(asset_data->properties, prop);
184}
185
186IDProperty *BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
187{
188 if (!asset_data->properties) {
189 return nullptr;
190 }
191 return IDP_GetPropertyFromGroup(asset_data->properties, name);
192}
193
194/* Queries -------------------------------------------- */
195
197 const ID *owner_id)
198{
199 return BKE_previewimg_id_get(owner_id);
200}
201
202/* .blend file API -------------------------------------------- */
203
205{
206 BLO_write_struct(writer, AssetMetaData, asset_data);
207
208 if (asset_data->properties) {
209 IDP_BlendWrite(writer, asset_data->properties);
210 }
211
212 BLO_write_string(writer, asset_data->author);
213 BLO_write_string(writer, asset_data->description);
214 BLO_write_string(writer, asset_data->copyright);
215 BLO_write_string(writer, asset_data->license);
216
217 LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
218 BLO_write_struct(writer, AssetTag, tag);
219 }
220}
221
223{
224 /* asset_data itself has been read already. */
225 asset_data->local_type_info = nullptr;
226
227 if (asset_data->properties) {
228 BLO_read_struct(reader, IDProperty, &asset_data->properties);
229 IDP_BlendDataRead(reader, &asset_data->properties);
230 }
231
232 BLO_read_string(reader, &asset_data->author);
233 BLO_read_string(reader, &asset_data->description);
234 BLO_read_string(reader, &asset_data->copyright);
235 BLO_read_string(reader, &asset_data->license);
236
237 BLO_read_struct_list(reader, AssetTag, &asset_data->tags);
238 BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
239}
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:763
#define IDP_BlendDataRead(reader, prop)
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1227
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:861
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
Definition idprop.cc:1437
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:669
PreviewImage * BKE_previewimg_id_get(const ID *id)
#define BLI_assert(a)
Definition BLI_assert.h:50
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
Definition string.c:45
#define STRNCPY_UTF8(dst, src)
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
bUUID BLI_uuid_nil(void)
Definition uuid.cc:73
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
Definition readfile.cc:4992
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct(reader, struct_name, ptr_p)
ID and Library types, which are fundamental for SDNA.
#define DNA_struct_default_get(struct_name)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
AssetMetaData * BKE_asset_metadata_copy(const AssetMetaData *source)
Definition asset.cc:44
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
Definition asset.cc:175
IDProperty * BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
Definition asset.cc:186
void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
Definition asset.cc:222
PreviewImage * BKE_asset_metadata_preview_get_from_id(const AssetMetaData *, const ID *owner_id)
Definition asset.cc:196
AssetMetaData * BKE_asset_metadata_create()
Definition asset.cc:32
AssetTagEnsureResult BKE_asset_metadata_tag_ensure(AssetMetaData *asset_data, const char *name)
Definition asset.cc:118
void BKE_asset_metadata_free(AssetMetaData **asset_data)
Definition asset.cc:38
void BKE_asset_metadata_catalog_id_clear(AssetMetaData *asset_data)
Definition asset.cc:154
void BKE_asset_library_reference_init_default(AssetLibraryReference *library_ref)
Definition asset.cc:149
void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
Definition asset.cc:204
static AssetTag * asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
Definition asset.cc:98
AssetTag * BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name)
Definition asset.cc:111
void BKE_asset_metadata_catalog_id_set(AssetMetaData *asset_data, const ::bUUID catalog_id, const char *catalog_simple_name)
Definition asset.cc:160
void BKE_asset_metadata_tag_remove(AssetMetaData *asset_data, AssetTag *tag)
Definition asset.cc:140
void copy(char *dst, int64_t dst_size) const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr StringRef trim() const
#define offsetof(t, d)
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
The meta-data of an asset. By creating and giving this for a data-block (ID.asset_data),...
char catalog_simple_name[64]
struct IDProperty * properties
struct AssetTypeInfo * local_type_info
struct bUUID catalog_id
User defined tag. Currently only used by assets, could be used more often at some point....
char name[64]
Definition DNA_ID.h:413