Blender V5.0
idtype.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <array>
10#include <cstring>
11
12#include "BLI_ghash.h"
13#include "BLI_utildefines.h"
14
15#include "BLT_translation.hh"
16
17#include "DNA_ID.h"
19#include "DNA_node_types.h"
20#include "DNA_scene_types.h"
21
22#include "BKE_node.hh"
23
24#include "BKE_idtype.hh"
25
26// static CLG_LogRef LOG = {"lib.idtype"};
27
29{
30 const IDCacheKey *key = static_cast<const IDCacheKey *>(key_v);
33 return uint(hash);
34}
35
36bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
37{
38 const IDCacheKey *key_a = static_cast<const IDCacheKey *>(key_a_v);
39 const IDCacheKey *key_b = static_cast<const IDCacheKey *>(key_b_v);
40 return (key_a->id_session_uid != key_b->id_session_uid) ||
41 (key_a->identifier != key_b->identifier);
42}
43
44static std::array<IDTypeInfo *, INDEX_ID_MAX> id_types;
45
46static void id_type_init()
47{
48 int init_types_num = 0;
49
50#define INIT_TYPE(_id_code) \
51 { \
52 BLI_assert(IDType_##_id_code.main_listbase_index == INDEX_##_id_code); \
53 id_types[INDEX_##_id_code] = &IDType_##_id_code; \
54 init_types_num++; \
55 } \
56 (void)0
57
97
98 /* Special case. */
101 init_types_num++;
102
103 BLI_assert_msg(init_types_num == INDEX_ID_MAX, "Some IDTypeInfo initialization is missing");
104 UNUSED_VARS_NDEBUG(init_types_num);
105
106 { /* Inspect which ID types can be animated, so that IDType_ID_AC.dependencies_id_types can be
107 * set to include those. The runtime ID* cache of #animrig::Slot will point to any
108 * ID that is animated by it, and thus can point to any animatable ID type. */
109 IDType_ID_AC.dependencies_id_types = 0;
110 for (const IDTypeInfo *id_type : id_types) {
111 const bool is_animatable = (id_type->flags & IDTYPE_FLAGS_NO_ANIMDATA) == 0;
112 if (is_animatable) {
113 IDType_ID_AC.dependencies_id_types |= id_type->id_filter;
114 }
115 }
116 }
117
118#undef INIT_TYPE
119}
120
122{
123 /* Initialize data-block types. */
124 id_type_init();
125}
126
128{
129 if (idtype_index >= 0 && idtype_index < int(id_types.size())) {
130 const IDTypeInfo *id_type = id_types[size_t(idtype_index)];
131 if (id_type && id_type->name[0] != '\0') {
132 BLI_assert_msg(BKE_idtype_idcode_to_index(id_type->id_code) == idtype_index,
133 "Critical inconsistency in ID type information");
134 return id_type;
135 }
136 }
137
138 return nullptr;
139}
140
145
150
151static const IDTypeInfo *idtype_get_info_from_name(const char *idtype_name)
152{
153 for (const IDTypeInfo *id_type : id_types) {
154 if (id_type && STREQ(idtype_name, id_type->name)) {
155 return id_type;
156 }
157 }
158
159 return nullptr;
160}
161
162/* Various helpers/wrappers around #IDTypeInfo structure. */
163
164const char *BKE_idtype_idcode_to_name(const short idcode)
165{
166 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
167 BLI_assert(id_type != nullptr);
168 return id_type != nullptr ? id_type->name : nullptr;
169}
170
171const char *BKE_idtype_idcode_to_name_plural(const short idcode)
172{
173 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
174 BLI_assert(id_type != nullptr);
175 return id_type != nullptr ? id_type->name_plural : nullptr;
176}
177
178const char *BKE_idtype_idcode_to_translation_context(const short idcode)
179{
180 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
181 BLI_assert(id_type != nullptr);
182 return id_type != nullptr ? id_type->translation_context : BLT_I18NCONTEXT_DEFAULT;
183}
184
185short BKE_idtype_idcode_from_name(const char *idtype_name)
186{
187 const IDTypeInfo *id_type = idtype_get_info_from_name(idtype_name);
188 BLI_assert(id_type);
189 return id_type != nullptr ? id_type->id_code : 0;
190}
191
192bool BKE_idtype_idcode_is_valid(const short idcode)
193{
194 return BKE_idtype_get_info_from_idcode(idcode) != nullptr ? true : false;
195}
196
197bool BKE_idtype_idcode_is_linkable(const short idcode)
198{
199 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
200 BLI_assert(id_type != nullptr);
201 return id_type != nullptr ? (id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0 : false;
202}
203
205{
206 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
207 BLI_assert(id_type != nullptr);
208 if (id_type != nullptr && (id_type->flags & IDTYPE_FLAGS_ONLY_APPEND) != 0) {
209 /* Only appendable ID types should also always be linkable. */
211 return true;
212 }
213 return false;
214}
215
217{
218 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
219 BLI_assert(id_type != nullptr);
220 if (id_type != nullptr && (id_type->flags & IDTYPE_FLAGS_APPEND_IS_REUSABLE) != 0) {
221 /* All appendable ID types should also always be linkable. */
223 return true;
224 }
225 return false;
226}
227
228int BKE_idtype_idcode_to_index(const short idcode)
229{
230#define CASE_IDINDEX(_id) \
231 case ID_##_id: \
232 return INDEX_ID_##_id
233
234 switch ((ID_Type)idcode) {
235 CASE_IDINDEX(AC);
236 CASE_IDINDEX(AR);
238 CASE_IDINDEX(CA);
239 CASE_IDINDEX(CF);
240 CASE_IDINDEX(CU_LEGACY);
241 CASE_IDINDEX(GD_LEGACY);
242 CASE_IDINDEX(GP);
243 CASE_IDINDEX(GR);
245 CASE_IDINDEX(IM);
246 CASE_IDINDEX(KE);
247 CASE_IDINDEX(LA);
248 CASE_IDINDEX(LI);
249 CASE_IDINDEX(LS);
251 CASE_IDINDEX(MA);
252 CASE_IDINDEX(MB);
253 CASE_IDINDEX(MC);
254 CASE_IDINDEX(ME);
255 CASE_IDINDEX(MSK);
256 CASE_IDINDEX(NT);
257 CASE_IDINDEX(OB);
258 CASE_IDINDEX(PA);
259 CASE_IDINDEX(PAL);
260 CASE_IDINDEX(PC);
261 CASE_IDINDEX(PT);
262 CASE_IDINDEX(LP);
263 CASE_IDINDEX(SCE);
264 CASE_IDINDEX(SCR);
265 CASE_IDINDEX(SPK);
266 CASE_IDINDEX(SO);
267 CASE_IDINDEX(TE);
268 CASE_IDINDEX(TXT);
269 CASE_IDINDEX(VF);
270 CASE_IDINDEX(VO);
271 CASE_IDINDEX(WM);
272 CASE_IDINDEX(WO);
273 CASE_IDINDEX(WS);
274 }
275
276 /* Special naughty boy... */
277 if (idcode == ID_LINK_PLACEHOLDER) {
278 return INDEX_ID_NULL;
279 }
280
281 return -1;
282
283#undef CASE_IDINDEX
284}
285
287{
288#define CASE_IDINDEX(_id) \
289 case FILTER_ID_##_id: \
290 return INDEX_ID_##_id
291
292 switch (id_filter) {
293 CASE_IDINDEX(AC);
294 CASE_IDINDEX(AR);
296 CASE_IDINDEX(CA);
297 CASE_IDINDEX(CF);
298 CASE_IDINDEX(CU_LEGACY);
299 CASE_IDINDEX(GD_LEGACY);
300 CASE_IDINDEX(GP);
301 CASE_IDINDEX(GR);
303 CASE_IDINDEX(IM);
304 CASE_IDINDEX(KE);
305 CASE_IDINDEX(LA);
306 CASE_IDINDEX(LI);
307 CASE_IDINDEX(LS);
309 CASE_IDINDEX(MA);
310 CASE_IDINDEX(MB);
311 CASE_IDINDEX(MC);
312 CASE_IDINDEX(ME);
313 CASE_IDINDEX(MSK);
314 CASE_IDINDEX(NT);
315 CASE_IDINDEX(OB);
316 CASE_IDINDEX(PA);
317 CASE_IDINDEX(PAL);
318 CASE_IDINDEX(PC);
319 CASE_IDINDEX(PT);
320 CASE_IDINDEX(LP);
321 CASE_IDINDEX(SCE);
322 CASE_IDINDEX(SCR);
323 CASE_IDINDEX(SPK);
324 CASE_IDINDEX(SO);
325 CASE_IDINDEX(TE);
326 CASE_IDINDEX(TXT);
327 CASE_IDINDEX(VF);
328 CASE_IDINDEX(VO);
329 CASE_IDINDEX(WM);
330 CASE_IDINDEX(WO);
331 CASE_IDINDEX(WS);
332 }
333
334 /* No handling of #ID_LINK_PLACEHOLDER or #INDEX_ID_NULL here. */
335
336 return -1;
337
338#undef CASE_IDINDEX
339}
340
341short BKE_idtype_index_to_idcode(const int idtype_index)
342{
343 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idtype_index(idtype_index);
344 if (id_type) {
345 return id_type->id_code;
346 }
347
349 return -1;
350}
351
353{
354 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idtype_index(idtype_index);
355 if (id_type) {
356 return id_type->id_filter;
357 }
358
360 return 0;
361}
362
367
372
373short BKE_idtype_idcode_iter_step(int *idtype_index)
374{
375 return (*idtype_index < int(id_types.size())) ? BKE_idtype_index_to_idcode((*idtype_index)++) :
376 0;
377}
378
380 IDTypeForeachCacheFunctionCallback function_callback,
381 void *user_data)
382{
383 const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
384 if (type_info->foreach_cache != nullptr) {
385 type_info->foreach_cache(id, function_callback, user_data);
386 }
387
388 /* Handle 'private IDs'. */
390 if (nodetree != nullptr) {
391 type_info = BKE_idtype_get_info_from_id(&nodetree->id);
392 if (type_info == nullptr) {
393 /* Very old .blend file seem to have empty names for their embedded node trees, see
394 * `blo_do_versions_250()`. Assume those are node-trees then. */
396 }
397 if (type_info->foreach_cache != nullptr) {
398 type_info->foreach_cache(&nodetree->id, function_callback, user_data);
399 }
400 }
401
402 if (GS(id->name) == ID_SCE) {
403 Scene *scene = (Scene *)id;
404 if (scene->master_collection != nullptr) {
406 if (type_info->foreach_cache != nullptr) {
407 type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data);
408 }
409 }
410 }
411}
void(*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data) IDTypeForeachCacheFunctionCallback
IDTypeInfo IDType_ID_AC
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition BKE_idtype.hh:47
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition BKE_idtype.hh:49
@ IDTYPE_FLAGS_ONLY_APPEND
Definition BKE_idtype.hh:41
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition BKE_idtype.hh:35
IDTypeInfo IDType_ID_LINK_PLACEHOLDER
Definition lib_id.cc:88
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
unsigned int BLI_ghashutil_uinthash(unsigned int key)
unsigned int uint
#define UNUSED_VARS_NDEBUG(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_DEFAULT
ID and Library types, which are fundamental for SDNA.
#define INDEX_ID_MAX
Definition DNA_ID.h:1360
@ INDEX_ID_NULL
Definition DNA_ID.h:1357
ID_Type
@ ID_WM
@ ID_CA
@ ID_AR
@ ID_MC
@ ID_CF
@ ID_LI
@ ID_TE
@ ID_IM
@ ID_VO
@ ID_WS
@ ID_NT
@ ID_LA
@ ID_KE
@ ID_TXT
@ ID_SO
@ ID_SCE
@ ID_LS
@ ID_MSK
@ ID_CV
@ ID_PAL
@ ID_BR
@ ID_LP
@ ID_WO
@ ID_MA
@ ID_AC
@ ID_SCR
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_VF
@ ID_ME
@ ID_GR
@ ID_SPK
@ ID_MB
@ ID_LT
@ ID_OB
@ ID_GP
@ ID_PA
@ ID_PT
@ ID_PC
#define ID_LINK_PLACEHOLDER
Object groups, one object can be in many groups at once.
return true
#define BR
Definition boxpack_2d.cc:77
unsigned long long int uint64_t
#define GS(x)
#define INIT_TYPE(_id_code)
#define CASE_IDINDEX(_id)
const IDTypeInfo * BKE_idtype_get_info_from_idtype_index(const int idtype_index)
Definition idtype.cc:127
const IDTypeInfo * BKE_idtype_get_info_from_idcode(const short id_code)
Definition idtype.cc:141
static void id_type_init()
Definition idtype.cc:46
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
Definition idtype.cc:146
const char * BKE_idtype_idcode_to_name_plural(const short idcode)
Definition idtype.cc:171
const char * BKE_idtype_idcode_to_name(const short idcode)
Definition idtype.cc:164
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
Definition idtype.cc:36
const char * BKE_idtype_idcode_to_translation_context(const short idcode)
Definition idtype.cc:178
bool BKE_idtype_idcode_is_only_appendable(const short idcode)
Definition idtype.cc:204
bool BKE_idtype_idcode_is_linkable(const short idcode)
Definition idtype.cc:197
bool BKE_idtype_idcode_is_valid(const short idcode)
Definition idtype.cc:192
static const IDTypeInfo * idtype_get_info_from_name(const char *idtype_name)
Definition idtype.cc:151
void BKE_idtype_init()
Definition idtype.cc:121
int BKE_idtype_idfilter_to_index(const uint64_t id_filter)
Definition idtype.cc:286
void BKE_idtype_id_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition idtype.cc:379
short BKE_idtype_idcode_from_name(const char *idtype_name)
Definition idtype.cc:185
short BKE_idtype_idfilter_to_idcode(const uint64_t idfilter)
Definition idtype.cc:368
bool BKE_idtype_idcode_append_is_reusable(const short idcode)
Definition idtype.cc:216
static std::array< IDTypeInfo *, INDEX_ID_MAX > id_types
Definition idtype.cc:44
short BKE_idtype_idcode_iter_step(int *idtype_index)
Definition idtype.cc:373
int BKE_idtype_idcode_to_index(const short idcode)
Definition idtype.cc:228
short BKE_idtype_index_to_idcode(const int idtype_index)
Definition idtype.cc:341
uint64_t BKE_idtype_index_to_idfilter(const int idtype_index)
Definition idtype.cc:352
uint BKE_idtype_cache_key_hash(const void *key_v)
Definition idtype.cc:28
uint64_t BKE_idtype_idcode_to_idfilter(const short idcode)
Definition idtype.cc:363
#define LT
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:4568
#define CV
#define hash
Definition noise_c.cc:154
unsigned int id_session_uid
Definition BKE_idtype.hh:77
size_t identifier
Definition BKE_idtype.hh:82
short id_code
const char * name
const char * name_plural
IDTypeForeachCacheFunction foreach_cache
uint64_t id_filter
uint32_t flags
const char * translation_context
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct Collection * master_collection