Blender  V3.3
asset.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <cstring>
8 
9 #include "DNA_ID.h"
10 #include "DNA_defaults.h"
11 
12 #include "BLI_listbase.h"
13 #include "BLI_string.h"
14 #include "BLI_string_ref.hh"
15 #include "BLI_string_utils.h"
16 #include "BLI_uuid.h"
17 
18 #include "BKE_asset.h"
19 #include "BKE_icons.h"
20 #include "BKE_idprop.h"
21 
22 #include "BLO_read_write.h"
23 
24 #include "MEM_guardedalloc.h"
25 
26 using namespace blender;
27 
29 {
30  AssetMetaData *asset_data = (AssetMetaData *)MEM_callocN(sizeof(*asset_data), __func__);
31  memcpy(asset_data, DNA_struct_default_get(AssetMetaData), sizeof(*asset_data));
32  return asset_data;
33 }
34 
36 {
37  if ((*asset_data)->properties) {
38  IDP_FreeProperty((*asset_data)->properties);
39  }
40  MEM_SAFE_FREE((*asset_data)->author);
41  MEM_SAFE_FREE((*asset_data)->description);
42  BLI_freelistN(&(*asset_data)->tags);
43 
44  MEM_SAFE_FREE(*asset_data);
45 }
46 
47 static AssetTag *asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
48 {
49  AssetTag *tag = (AssetTag *)MEM_callocN(sizeof(*tag), __func__);
50  BLI_strncpy(tag->name, name, sizeof(tag->name));
51 
52  BLI_addtail(&asset_data->tags, tag);
53  asset_data->tot_tags++;
54  /* Invariant! */
55  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
56 
57  return tag;
58 }
59 
60 AssetTag *BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name)
61 {
62  AssetTag *tag = asset_metadata_tag_add(asset_data, name);
63  BLI_uniquename(&asset_data->tags, tag, name, '.', offsetof(AssetTag, name), sizeof(tag->name));
64  return tag;
65 }
66 
68  const char *name)
69 {
70  struct AssetTagEnsureResult result = {nullptr};
71  if (!name[0]) {
72  return result;
73  }
74 
75  AssetTag *tag = (AssetTag *)BLI_findstring(&asset_data->tags, name, offsetof(AssetTag, name));
76 
77  if (tag) {
78  result.tag = tag;
79  result.is_new = false;
80  return result;
81  }
82 
83  tag = asset_metadata_tag_add(asset_data, name);
84 
85  result.tag = tag;
86  result.is_new = true;
87  return result;
88 }
89 
91 {
92  BLI_assert(BLI_findindex(&asset_data->tags, tag) >= 0);
93  BLI_freelinkN(&asset_data->tags, tag);
94  asset_data->tot_tags--;
95  /* Invariant! */
96  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
97 }
98 
100 {
101  memcpy(library_ref, DNA_struct_default_get(AssetLibraryReference), sizeof(*library_ref));
102 }
103 
105 {
106  asset_data->catalog_id = BLI_uuid_nil();
107  asset_data->catalog_simple_name[0] = '\0';
108 }
109 
111  const ::bUUID catalog_id,
112  const char *catalog_simple_name)
113 {
114  asset_data->catalog_id = catalog_id;
115 
116  constexpr size_t max_simple_name_length = sizeof(asset_data->catalog_simple_name);
117 
118  /* The substr() call is necessary to make copy() copy the first N characters (instead of refusing
119  * to copy and producing an empty string). */
120  StringRef trimmed_id =
121  StringRef(catalog_simple_name).trim().substr(0, max_simple_name_length - 1);
122  trimmed_id.copy(asset_data->catalog_simple_name, max_simple_name_length);
123 }
124 
126 {
127  if (!asset_data->properties) {
128  IDPropertyTemplate val = {0};
129  asset_data->properties = IDP_New(IDP_GROUP, &val, "AssetMetaData.properties");
130  }
131  /* Important: The property may already exist. For now just allow always allow a newly allocated
132  * property, and replace the existing one as a way of updating. */
133  IDP_ReplaceInGroup(asset_data->properties, prop);
134 }
135 
136 IDProperty *BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
137 {
138  if (!asset_data->properties) {
139  return nullptr;
140  }
141  return IDP_GetPropertyFromGroup(asset_data->properties, name);
142 }
143 
144 /* Queries -------------------------------------------- */
145 
147  const ID *id)
148 {
149  return BKE_previewimg_id_get(id);
150 }
151 
152 /* .blend file API -------------------------------------------- */
153 
155 {
156  BLO_write_struct(writer, AssetMetaData, asset_data);
157 
158  if (asset_data->properties) {
159  IDP_BlendWrite(writer, asset_data->properties);
160  }
161 
162  if (asset_data->author) {
163  BLO_write_string(writer, asset_data->author);
164  }
165  if (asset_data->description) {
166  BLO_write_string(writer, asset_data->description);
167  }
168  LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
169  BLO_write_struct(writer, AssetTag, tag);
170  }
171 }
172 
174 {
175  /* asset_data itself has been read already. */
176  asset_data->local_type_info = nullptr;
177 
178  if (asset_data->properties) {
179  BLO_read_data_address(reader, &asset_data->properties);
180  IDP_BlendDataRead(reader, &asset_data->properties);
181  }
182 
183  BLO_read_data_address(reader, &asset_data->author);
184  BLO_read_data_address(reader, &asset_data->description);
185  BLO_read_list(reader, &asset_data->tags);
186  BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
187 }
struct PreviewImage * BKE_previewimg_id_get(const struct ID *id)
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL()
Definition: idprop.c:578
struct IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: idprop.c:887
#define IDP_BlendDataRead(reader, prop)
Definition: BKE_idprop.h:321
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1093
struct IDProperty * IDP_GetPropertyFromGroup(const struct IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
#define UNUSED(x)
bUUID BLI_uuid_nil(void)
Definition: uuid.cc:70
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1601
ID and Library types, which are fundamental for sdna.
@ IDP_GROUP
Definition: DNA_ID.h:141
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
struct bUUID bUUID
Universally Unique Identifier according to RFC4122.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
IDProperty * BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
Definition: asset.cc:136
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
Definition: asset.cc:125
AssetMetaData * BKE_asset_metadata_create()
Definition: asset.cc:28
AssetTag * BKE_asset_metadata_tag_add(AssetMetaData *asset_data, const char *name)
Definition: asset.cc:60
static AssetTag * asset_metadata_tag_add(AssetMetaData *asset_data, const char *const name)
Definition: asset.cc:47
void BKE_asset_metadata_catalog_id_set(struct AssetMetaData *asset_data, const ::bUUID catalog_id, const char *catalog_simple_name)
Definition: asset.cc:110
void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
Definition: asset.cc:173
void BKE_asset_metadata_catalog_id_clear(struct AssetMetaData *asset_data)
Definition: asset.cc:104
void BKE_asset_metadata_free(AssetMetaData **asset_data)
Definition: asset.cc:35
struct AssetTagEnsureResult BKE_asset_metadata_tag_ensure(AssetMetaData *asset_data, const char *name)
Definition: asset.cc:67
void BKE_asset_library_reference_init_default(AssetLibraryReference *library_ref)
Definition: asset.cc:99
void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
Definition: asset.cc:154
PreviewImage * BKE_asset_metadata_preview_get_from_id(const AssetMetaData *UNUSED(asset_data), const ID *id)
Definition: asset.cc:146
void BKE_asset_metadata_tag_remove(AssetMetaData *asset_data, AssetTag *tag)
Definition: asset.cc:90
void copy(char *dst, int64_t dst_size) const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr StringRef trim() const
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
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
struct AssetTag * tag
Definition: BKE_asset.h:40
User defined tag. Currently only used by assets, could be used more often at some point....
char name[64]
Definition: DNA_ID.h:368