Blender V4.3
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
9#include <array>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_ghash.h"
15#include "BLI_utildefines.h"
16
17#include "CLG_log.h"
18
19#include "BLT_translation.hh"
20
21#include "DNA_ID.h"
23#include "DNA_node_types.h"
24#include "DNA_scene_types.h"
25
26#include "BKE_main.hh"
27#include "BKE_node.hh"
28
29#include "BKE_idtype.hh"
30
31// static CLG_LogRef LOG = {"bke.idtype"};
32
34{
35 const IDCacheKey *key = static_cast<const IDCacheKey *>(key_v);
38 return uint(hash);
39}
40
41bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
42{
43 const IDCacheKey *key_a = static_cast<const IDCacheKey *>(key_a_v);
44 const IDCacheKey *key_b = static_cast<const IDCacheKey *>(key_b_v);
45 return (key_a->id_session_uid != key_b->id_session_uid) ||
46 (key_a->identifier != key_b->identifier);
47}
48
49static std::array<IDTypeInfo *, INDEX_ID_MAX> id_types;
50
51static void id_type_init()
52{
53 int init_types_num = 0;
54
55#define INIT_TYPE(_id_code) \
56 { \
57 BLI_assert(IDType_##_id_code.main_listbase_index == INDEX_##_id_code); \
58 id_types[INDEX_##_id_code] = &IDType_##_id_code; \
59 init_types_num++; \
60 } \
61 (void)0
62
103
104 /* Special case. */
107 init_types_num++;
108
109 BLI_assert_msg(init_types_num == INDEX_ID_MAX, "Some IDTypeInfo initialization is missing");
110 UNUSED_VARS_NDEBUG(init_types_num);
111
112 { /* Inspect which ID types can be animated, so that IDType_ID_AC.dependencies_id_types can be
113 * set to include those. The runtime ID* cache of #animrig::Slot will point to any
114 * ID that is animated by it, and thus can point to any animatable ID type. */
116 for (const IDTypeInfo *id_type : id_types) {
117 const bool is_animatable = (id_type->flags & IDTYPE_FLAGS_NO_ANIMDATA) == 0;
118 if (is_animatable) {
119 IDType_ID_AC.dependencies_id_types |= id_type->id_filter;
120 }
121 }
122 }
123
124#undef INIT_TYPE
125}
126
128{
129 /* Initialize data-block types. */
130 id_type_init();
131}
132
134{
135 if (idtype_index >= 0 && idtype_index < int(id_types.size())) {
136 const IDTypeInfo *id_type = id_types[size_t(idtype_index)];
137 if (id_type && id_type->name[0] != '\0') {
138 return id_type;
139 }
140 }
141
142 return nullptr;
143}
144
149
151{
152 return BKE_idtype_get_info_from_idcode(GS(id->name));
153}
154
155static const IDTypeInfo *idtype_get_info_from_name(const char *idtype_name)
156{
157 for (const IDTypeInfo *id_type : id_types) {
158 if (id_type && STREQ(idtype_name, id_type->name)) {
159 return id_type;
160 }
161 }
162
163 return nullptr;
164}
165
166/* Various helpers/wrappers around #IDTypeInfo structure. */
167
168const char *BKE_idtype_idcode_to_name(const short idcode)
169{
170 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
171 BLI_assert(id_type != nullptr);
172 return id_type != nullptr ? id_type->name : nullptr;
173}
174
175const char *BKE_idtype_idcode_to_name_plural(const short idcode)
176{
177 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
178 BLI_assert(id_type != nullptr);
179 return id_type != nullptr ? id_type->name_plural : nullptr;
180}
181
182const char *BKE_idtype_idcode_to_translation_context(const short idcode)
183{
184 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
185 BLI_assert(id_type != nullptr);
186 return id_type != nullptr ? id_type->translation_context : BLT_I18NCONTEXT_DEFAULT;
187}
188
189short BKE_idtype_idcode_from_name(const char *idtype_name)
190{
191 const IDTypeInfo *id_type = idtype_get_info_from_name(idtype_name);
192 BLI_assert(id_type);
193 return id_type != nullptr ? id_type->id_code : 0;
194}
195
196bool BKE_idtype_idcode_is_valid(const short idcode)
197{
198 return BKE_idtype_get_info_from_idcode(idcode) != nullptr ? true : false;
199}
200
201bool BKE_idtype_idcode_is_linkable(const short idcode)
202{
203 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
204 BLI_assert(id_type != nullptr);
205 return id_type != nullptr ? (id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0 : false;
206}
207
209{
210 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
211 BLI_assert(id_type != nullptr);
212 if (id_type != nullptr && (id_type->flags & IDTYPE_FLAGS_ONLY_APPEND) != 0) {
213 /* Only appendable ID types should also always be linkable. */
215 return true;
216 }
217 return false;
218}
219
221{
222 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
223 BLI_assert(id_type != nullptr);
224 if (id_type != nullptr && (id_type->flags & IDTYPE_FLAGS_APPEND_IS_REUSABLE) != 0) {
225 /* All appendable ID types should also always be linkable. */
227 return true;
228 }
229 return false;
230}
231
232int BKE_idtype_idcode_to_index(const short idcode)
233{
234#define CASE_IDINDEX(_id) \
235 case ID_##_id: \
236 return INDEX_ID_##_id
237
238 switch ((ID_Type)idcode) {
239 CASE_IDINDEX(AC);
240 CASE_IDINDEX(AR);
242 CASE_IDINDEX(CA);
243 CASE_IDINDEX(CF);
244 CASE_IDINDEX(CU_LEGACY);
245 CASE_IDINDEX(GD_LEGACY);
246 CASE_IDINDEX(GP);
247 CASE_IDINDEX(GR);
249 CASE_IDINDEX(IM);
250 CASE_IDINDEX(IP);
251 CASE_IDINDEX(KE);
252 CASE_IDINDEX(LA);
253 CASE_IDINDEX(LI);
254 CASE_IDINDEX(LS);
256 CASE_IDINDEX(MA);
257 CASE_IDINDEX(MB);
258 CASE_IDINDEX(MC);
259 CASE_IDINDEX(ME);
260 CASE_IDINDEX(MSK);
261 CASE_IDINDEX(NT);
262 CASE_IDINDEX(OB);
263 CASE_IDINDEX(PA);
264 CASE_IDINDEX(PAL);
265 CASE_IDINDEX(PC);
266 CASE_IDINDEX(PT);
267 CASE_IDINDEX(LP);
268 CASE_IDINDEX(SCE);
269 CASE_IDINDEX(SCR);
270 CASE_IDINDEX(SPK);
271 CASE_IDINDEX(SO);
272 CASE_IDINDEX(TE);
273 CASE_IDINDEX(TXT);
274 CASE_IDINDEX(VF);
275 CASE_IDINDEX(VO);
276 CASE_IDINDEX(WM);
277 CASE_IDINDEX(WO);
278 CASE_IDINDEX(WS);
279 }
280
281 /* Special naughty boy... */
282 if (idcode == ID_LINK_PLACEHOLDER) {
283 return INDEX_ID_NULL;
284 }
285
286 return -1;
287
288#undef CASE_IDINDEX
289}
290
292{
293#define CASE_IDINDEX(_id) \
294 case FILTER_ID_##_id: \
295 return INDEX_ID_##_id
296
297 switch (id_filter) {
298 CASE_IDINDEX(AC);
299 CASE_IDINDEX(AR);
301 CASE_IDINDEX(CA);
302 CASE_IDINDEX(CF);
303 CASE_IDINDEX(CU_LEGACY);
304 CASE_IDINDEX(GD_LEGACY);
305 CASE_IDINDEX(GP);
306 CASE_IDINDEX(GR);
308 CASE_IDINDEX(IM);
309 CASE_IDINDEX(IP);
310 CASE_IDINDEX(KE);
311 CASE_IDINDEX(LA);
312 CASE_IDINDEX(LI);
313 CASE_IDINDEX(LS);
315 CASE_IDINDEX(MA);
316 CASE_IDINDEX(MB);
317 CASE_IDINDEX(MC);
318 CASE_IDINDEX(ME);
319 CASE_IDINDEX(MSK);
320 CASE_IDINDEX(NT);
321 CASE_IDINDEX(OB);
322 CASE_IDINDEX(PA);
323 CASE_IDINDEX(PAL);
324 CASE_IDINDEX(PC);
325 CASE_IDINDEX(PT);
326 CASE_IDINDEX(LP);
327 CASE_IDINDEX(SCE);
328 CASE_IDINDEX(SCR);
329 CASE_IDINDEX(SPK);
330 CASE_IDINDEX(SO);
331 CASE_IDINDEX(TE);
332 CASE_IDINDEX(TXT);
333 CASE_IDINDEX(VF);
334 CASE_IDINDEX(VO);
335 CASE_IDINDEX(WM);
336 CASE_IDINDEX(WO);
337 CASE_IDINDEX(WS);
338 }
339
340 /* No handling of #ID_LINK_PLACEHOLDER or #INDEX_ID_NULL here. */
341
342 return -1;
343
344#undef CASE_IDINDEX
345}
346
347short BKE_idtype_index_to_idcode(const int idtype_index)
348{
349 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idtype_index(idtype_index);
350 if (id_type) {
351 return id_type->id_code;
352 }
353
355 return -1;
356}
357
359{
360 const IDTypeInfo *id_type = BKE_idtype_get_info_from_idtype_index(idtype_index);
361 if (id_type) {
362 return id_type->id_filter;
363 }
364
366 return 0;
367}
368
373
378
379short BKE_idtype_idcode_iter_step(int *idtype_index)
380{
381 return (*idtype_index < int(id_types.size())) ? BKE_idtype_index_to_idcode((*idtype_index)++) :
382 0;
383}
384
386 IDTypeForeachCacheFunctionCallback function_callback,
387 void *user_data)
388{
389 const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
390 if (type_info->foreach_cache != nullptr) {
391 type_info->foreach_cache(id, function_callback, user_data);
392 }
393
394 /* Handle 'private IDs'. */
396 if (nodetree != nullptr) {
397 type_info = BKE_idtype_get_info_from_id(&nodetree->id);
398 if (type_info == nullptr) {
399 /* Very old .blend file seem to have empty names for their embedded node trees, see
400 * `blo_do_versions_250()`. Assume those are node-trees then. */
402 }
403 if (type_info->foreach_cache != nullptr) {
404 type_info->foreach_cache(&nodetree->id, function_callback, user_data);
405 }
406 }
407
408 if (GS(id->name) == ID_SCE) {
409 Scene *scene = (Scene *)id;
410 if (scene->master_collection != nullptr) {
411 type_info = BKE_idtype_get_info_from_id(&scene->master_collection->id);
412 if (type_info->foreach_cache != nullptr) {
413 type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data);
414 }
415 }
416 }
417}
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition BKE_idtype.hh:39
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition BKE_idtype.hh:41
@ IDTYPE_FLAGS_ONLY_APPEND
Definition BKE_idtype.hh:36
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition BKE_idtype.hh:32
void(*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data) IDTypeForeachCacheFunctionCallback
Definition BKE_idtype.hh:98
IDTypeInfo IDType_ID_AC
IDTypeInfo IDType_ID_LINK_PLACEHOLDER
Definition lib_id.cc:87
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
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:1328
@ INDEX_ID_NULL
Definition DNA_ID.h:1325
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_IP
@ 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.
Read Guarded memory(de)allocation.
#define BR
Definition boxpack_2d.c:86
#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:133
const IDTypeInfo * BKE_idtype_get_info_from_idcode(const short id_code)
Definition idtype.cc:145
static void id_type_init()
Definition idtype.cc:51
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
Definition idtype.cc:150
const char * BKE_idtype_idcode_to_name_plural(const short idcode)
Definition idtype.cc:175
const char * BKE_idtype_idcode_to_name(const short idcode)
Definition idtype.cc:168
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
Definition idtype.cc:41
const char * BKE_idtype_idcode_to_translation_context(const short idcode)
Definition idtype.cc:182
bool BKE_idtype_idcode_is_only_appendable(const short idcode)
Definition idtype.cc:208
bool BKE_idtype_idcode_is_linkable(const short idcode)
Definition idtype.cc:201
bool BKE_idtype_idcode_is_valid(const short idcode)
Definition idtype.cc:196
static const IDTypeInfo * idtype_get_info_from_name(const char *idtype_name)
Definition idtype.cc:155
void BKE_idtype_init()
Definition idtype.cc:127
int BKE_idtype_idfilter_to_index(const uint64_t id_filter)
Definition idtype.cc:291
void BKE_idtype_id_foreach_cache(ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition idtype.cc:385
short BKE_idtype_idcode_from_name(const char *idtype_name)
Definition idtype.cc:189
short BKE_idtype_idfilter_to_idcode(const uint64_t idfilter)
Definition idtype.cc:374
bool BKE_idtype_idcode_append_is_reusable(const short idcode)
Definition idtype.cc:220
static std::array< IDTypeInfo *, INDEX_ID_MAX > id_types
Definition idtype.cc:49
short BKE_idtype_idcode_iter_step(int *idtype_index)
Definition idtype.cc:379
int BKE_idtype_idcode_to_index(const short idcode)
Definition idtype.cc:232
short BKE_idtype_index_to_idcode(const int idtype_index)
Definition idtype.cc:347
uint64_t BKE_idtype_index_to_idfilter(const int idtype_index)
Definition idtype.cc:358
uint BKE_idtype_cache_key_hash(const void *key_v)
Definition idtype.cc:33
uint64_t BKE_idtype_idcode_to_idfilter(const short idcode)
Definition idtype.cc:369
#define GS(x)
Definition iris.cc:202
#define LT
bNodeTree * node_tree_from_id(ID *id)
Definition node.cc:3732
#define CV
#define hash
Definition noise.c:154
unsigned __int64 uint64_t
Definition stdint.h:90
unsigned int id_session_uid
Definition BKE_idtype.hh:69
size_t identifier
Definition BKE_idtype.hh:72
int main_listbase_index
short id_code
const char * name
uint64_t dependencies_id_types
const char * name_plural
IDTypeForeachCacheFunction foreach_cache
uint64_t id_filter
uint32_t flags
const char * translation_context
Definition DNA_ID.h:413