Blender  V3.3
idtype.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include <string.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_ghash.h"
13 #include "BLI_utildefines.h"
14 
15 #include "CLG_log.h"
16 
17 #include "BLT_translation.h"
18 
19 #include "DNA_ID.h"
20 #include "DNA_collection_types.h"
21 #include "DNA_node_types.h"
22 #include "DNA_scene_types.h"
23 
24 #include "BKE_main.h"
25 #include "BKE_node.h"
26 
27 #include "BKE_idtype.h"
28 
29 // static CLG_LogRef LOG = {"bke.idtype"};
30 
31 uint BKE_idtype_cache_key_hash(const void *key_v)
32 {
33  const IDCacheKey *key = key_v;
36  return (uint)hash;
37 }
38 
39 bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
40 {
41  const IDCacheKey *key_a = key_a_v;
42  const IDCacheKey *key_b = key_b_v;
43  return (key_a->id_session_uuid != key_b->id_session_uuid) ||
44  (key_a->offset_in_ID != key_b->offset_in_ID);
45 }
46 
48 
49 static void id_type_init(void)
50 {
51 #define INIT_TYPE(_id_code) \
52  { \
53  BLI_assert(IDType_##_id_code.main_listbase_index == INDEX_##_id_code); \
54  id_types[INDEX_##_id_code] = &IDType_##_id_code; \
55  } \
56  (void)0
57 
98 
99  /* Special naughty boy... */
102 
103 #undef INIT_TYPE
104 }
105 
106 void BKE_idtype_init(void)
107 {
108  /* Initialize data-block types. */
109  id_type_init();
110 }
111 
112 const IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code)
113 {
114  int id_index = BKE_idtype_idcode_to_index(id_code);
115 
116  if (id_index >= 0 && id_index < ARRAY_SIZE(id_types) && id_types[id_index] != NULL &&
117  id_types[id_index]->name[0] != '\0') {
118  return id_types[id_index];
119  }
120 
121  return NULL;
122 }
123 
125 {
127 }
128 
129 static const IDTypeInfo *idtype_get_info_from_name(const char *idtype_name)
130 {
131  for (int i = ARRAY_SIZE(id_types); i--;) {
132  if (id_types[i] != NULL && STREQ(idtype_name, id_types[i]->name)) {
133  return id_types[i];
134  }
135  }
136 
137  return NULL;
138 }
139 
140 /* Various helpers/wrappers around #IDTypeInfo structure. */
141 
142 const char *BKE_idtype_idcode_to_name(const short idcode)
143 {
144  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
145  BLI_assert(id_type != NULL);
146  return id_type != NULL ? id_type->name : NULL;
147 }
148 
149 const char *BKE_idtype_idcode_to_name_plural(const short idcode)
150 {
151  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
152  BLI_assert(id_type != NULL);
153  return id_type != NULL ? id_type->name_plural : NULL;
154 }
155 
156 const char *BKE_idtype_idcode_to_translation_context(const short idcode)
157 {
158  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
159  BLI_assert(id_type != NULL);
160  return id_type != NULL ? id_type->translation_context : BLT_I18NCONTEXT_DEFAULT;
161 }
162 
163 short BKE_idtype_idcode_from_name(const char *idtype_name)
164 {
165  const IDTypeInfo *id_type = idtype_get_info_from_name(idtype_name);
166  BLI_assert(id_type);
167  return id_type != NULL ? id_type->id_code : 0;
168 }
169 
170 bool BKE_idtype_idcode_is_valid(const short idcode)
171 {
172  return BKE_idtype_get_info_from_idcode(idcode) != NULL ? true : false;
173 }
174 
175 bool BKE_idtype_idcode_is_linkable(const short idcode)
176 {
177  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
178  BLI_assert(id_type != NULL);
179  return id_type != NULL ? (id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0 : false;
180 }
181 
182 bool BKE_idtype_idcode_is_only_appendable(const short idcode)
183 {
184  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
185  BLI_assert(id_type != NULL);
186  if (id_type != NULL && (id_type->flags & IDTYPE_FLAGS_ONLY_APPEND) != 0) {
187  /* Only appendable ID types should also always be linkable. */
188  BLI_assert((id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
189  return true;
190  }
191  return false;
192 }
193 
194 bool BKE_idtype_idcode_append_is_reusable(const short idcode)
195 {
196  const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
197  BLI_assert(id_type != NULL);
198  if (id_type != NULL && (id_type->flags & IDTYPE_FLAGS_APPEND_IS_REUSABLE) != 0) {
199  /* All appendable ID types should also always be linkable. */
200  BLI_assert((id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
201  return true;
202  }
203  return false;
204 }
205 
207 {
208 #define CASE_IDFILTER(_id) \
209  case ID_##_id: \
210  return FILTER_ID_##_id
211 
212 #define CASE_IDFILTER_NONE(_id) \
213  case ID_##_id: \
214  return 0
215 
216  switch ((ID_Type)idcode) {
217  CASE_IDFILTER(AC);
218  CASE_IDFILTER(AR);
219  CASE_IDFILTER(BR);
220  CASE_IDFILTER(CA);
221  CASE_IDFILTER(CF);
222  CASE_IDFILTER(CU_LEGACY);
223  CASE_IDFILTER(GD);
224  CASE_IDFILTER(GR);
225  CASE_IDFILTER(CV);
226  CASE_IDFILTER(IM);
227  CASE_IDFILTER_NONE(IP);
228  CASE_IDFILTER(KE);
229  CASE_IDFILTER(LA);
230  CASE_IDFILTER(LI);
231  CASE_IDFILTER(LP);
232  CASE_IDFILTER(LS);
233  CASE_IDFILTER(LT);
234  CASE_IDFILTER(MA);
235  CASE_IDFILTER(MB);
236  CASE_IDFILTER(MC);
237  CASE_IDFILTER(ME);
238  CASE_IDFILTER(MSK);
239  CASE_IDFILTER(NT);
240  CASE_IDFILTER(OB);
241  CASE_IDFILTER(PA);
242  CASE_IDFILTER(PAL);
243  CASE_IDFILTER(PC);
244  CASE_IDFILTER(PT);
245  CASE_IDFILTER(SCE);
246  CASE_IDFILTER(SCR);
247  CASE_IDFILTER(SIM);
248  CASE_IDFILTER(SO);
249  CASE_IDFILTER(SPK);
250  CASE_IDFILTER(TE);
251  CASE_IDFILTER(TXT);
252  CASE_IDFILTER(VF);
253  CASE_IDFILTER(VO);
254  CASE_IDFILTER(WM);
255  CASE_IDFILTER(WO);
256  CASE_IDFILTER(WS);
257  }
258 
260  return 0;
261 
262 #undef CASE_IDFILTER
263 #undef CASE_IDFILTER_NONE
264 }
265 
267 {
268 #define CASE_IDFILTER(_id) \
269  case FILTER_ID_##_id: \
270  return ID_##_id
271 
272 #define CASE_IDFILTER_NONE(_id) (void)0
273 
274  switch (idfilter) {
275  CASE_IDFILTER(AC);
276  CASE_IDFILTER(AR);
277  CASE_IDFILTER(BR);
278  CASE_IDFILTER(CA);
279  CASE_IDFILTER(CF);
280  CASE_IDFILTER(CU_LEGACY);
281  CASE_IDFILTER(GD);
282  CASE_IDFILTER(GR);
283  CASE_IDFILTER(CV);
284  CASE_IDFILTER(IM);
285  CASE_IDFILTER_NONE(IP);
286  CASE_IDFILTER(KE);
287  CASE_IDFILTER(LA);
288  CASE_IDFILTER(LI);
289  CASE_IDFILTER(LP);
290  CASE_IDFILTER(LS);
291  CASE_IDFILTER(LT);
292  CASE_IDFILTER(MA);
293  CASE_IDFILTER(MB);
294  CASE_IDFILTER(MC);
295  CASE_IDFILTER(ME);
296  CASE_IDFILTER(MSK);
297  CASE_IDFILTER(NT);
298  CASE_IDFILTER(OB);
299  CASE_IDFILTER(PA);
300  CASE_IDFILTER(PAL);
301  CASE_IDFILTER(PC);
302  CASE_IDFILTER(PT);
303  CASE_IDFILTER(SCE);
304  CASE_IDFILTER(SCR);
305  CASE_IDFILTER(SIM);
306  CASE_IDFILTER(SO);
307  CASE_IDFILTER(SPK);
308  CASE_IDFILTER(TE);
309  CASE_IDFILTER(TXT);
310  CASE_IDFILTER(VF);
311  CASE_IDFILTER(VO);
312  CASE_IDFILTER(WM);
313  CASE_IDFILTER(WO);
314  CASE_IDFILTER(WS);
315  }
316 
318  return 0;
319 
320 #undef CASE_IDFILTER
321 #undef CASE_IDFILTER_NONE
322 }
323 
324 int BKE_idtype_idcode_to_index(const short idcode)
325 {
326 #define CASE_IDINDEX(_id) \
327  case ID_##_id: \
328  return INDEX_ID_##_id
329 
330  switch ((ID_Type)idcode) {
331  CASE_IDINDEX(AC);
332  CASE_IDINDEX(AR);
333  CASE_IDINDEX(BR);
334  CASE_IDINDEX(CA);
335  CASE_IDINDEX(CF);
336  CASE_IDINDEX(CU_LEGACY);
337  CASE_IDINDEX(GD);
338  CASE_IDINDEX(GR);
339  CASE_IDINDEX(CV);
340  CASE_IDINDEX(IM);
341  CASE_IDINDEX(IP);
342  CASE_IDINDEX(KE);
343  CASE_IDINDEX(LA);
344  CASE_IDINDEX(LI);
345  CASE_IDINDEX(LS);
346  CASE_IDINDEX(LT);
347  CASE_IDINDEX(MA);
348  CASE_IDINDEX(MB);
349  CASE_IDINDEX(MC);
350  CASE_IDINDEX(ME);
351  CASE_IDINDEX(MSK);
352  CASE_IDINDEX(NT);
353  CASE_IDINDEX(OB);
354  CASE_IDINDEX(PA);
355  CASE_IDINDEX(PAL);
356  CASE_IDINDEX(PC);
357  CASE_IDINDEX(PT);
358  CASE_IDINDEX(LP);
359  CASE_IDINDEX(SCE);
360  CASE_IDINDEX(SCR);
361  CASE_IDINDEX(SIM);
362  CASE_IDINDEX(SPK);
363  CASE_IDINDEX(SO);
364  CASE_IDINDEX(TE);
365  CASE_IDINDEX(TXT);
366  CASE_IDINDEX(VF);
367  CASE_IDINDEX(VO);
368  CASE_IDINDEX(WM);
369  CASE_IDINDEX(WO);
370  CASE_IDINDEX(WS);
371  }
372 
373  /* Special naughty boy... */
374  if (idcode == ID_LINK_PLACEHOLDER) {
375  return INDEX_ID_NULL;
376  }
377 
378  return -1;
379 
380 #undef CASE_IDINDEX
381 }
382 
383 short BKE_idtype_idcode_from_index(const int index)
384 {
385 #define CASE_IDCODE(_id) \
386  case INDEX_ID_##_id: \
387  return ID_##_id
388 
389  switch (index) {
390  CASE_IDCODE(AC);
391  CASE_IDCODE(AR);
392  CASE_IDCODE(BR);
393  CASE_IDCODE(CA);
394  CASE_IDCODE(CF);
395  CASE_IDCODE(CU_LEGACY);
396  CASE_IDCODE(GD);
397  CASE_IDCODE(GR);
398  CASE_IDCODE(CV);
399  CASE_IDCODE(IM);
400  CASE_IDCODE(IP);
401  CASE_IDCODE(KE);
402  CASE_IDCODE(LA);
403  CASE_IDCODE(LI);
404  CASE_IDCODE(LS);
405  CASE_IDCODE(LT);
406  CASE_IDCODE(MA);
407  CASE_IDCODE(MB);
408  CASE_IDCODE(MC);
409  CASE_IDCODE(ME);
410  CASE_IDCODE(MSK);
411  CASE_IDCODE(NT);
412  CASE_IDCODE(OB);
413  CASE_IDCODE(PA);
414  CASE_IDCODE(PAL);
415  CASE_IDCODE(PC);
416  CASE_IDCODE(PT);
417  CASE_IDCODE(LP);
418  CASE_IDCODE(SCE);
419  CASE_IDCODE(SCR);
420  CASE_IDCODE(SIM);
421  CASE_IDCODE(SPK);
422  CASE_IDCODE(SO);
423  CASE_IDCODE(TE);
424  CASE_IDCODE(TXT);
425  CASE_IDCODE(VF);
426  CASE_IDCODE(VO);
427  CASE_IDCODE(WM);
428  CASE_IDCODE(WO);
429  CASE_IDCODE(WS);
430  }
431 
432  /* Special naughty boy... */
433  if (index == INDEX_ID_NULL) {
434  return ID_LINK_PLACEHOLDER;
435  }
436 
437  return -1;
438 
439 #undef CASE_IDCODE
440 }
441 
443 {
444  return (*index < ARRAY_SIZE(id_types)) ? BKE_idtype_idcode_from_index((*index)++) : 0;
445 }
446 
448  IDTypeForeachCacheFunctionCallback function_callback,
449  void *user_data)
450 {
451  const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(id);
452  if (type_info->foreach_cache != NULL) {
453  type_info->foreach_cache(id, function_callback, user_data);
454  }
455 
456  /* Handle 'private IDs'. */
457  bNodeTree *nodetree = ntreeFromID(id);
458  if (nodetree != NULL) {
459  type_info = BKE_idtype_get_info_from_id(&nodetree->id);
460  if (type_info == NULL) {
461  /* Very old .blend file seem to have empty names for their embedded node trees, see
462  * `blo_do_versions_250()`. Assume those are nodetrees then. */
464  }
465  if (type_info->foreach_cache != NULL) {
466  type_info->foreach_cache(&nodetree->id, function_callback, user_data);
467  }
468  }
469 
470  if (GS(id->name) == ID_SCE) {
471  Scene *scene = (Scene *)id;
472  if (scene->master_collection != NULL) {
474  if (type_info->foreach_cache != NULL) {
475  type_info->foreach_cache(&scene->master_collection->id, function_callback, user_data);
476  }
477  }
478  }
479 }
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
@ IDTYPE_FLAGS_ONLY_APPEND
Definition: BKE_idtype.h:36
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition: BKE_idtype.h:32
IDTypeInfo IDType_ID_LINK_PLACEHOLDER
Definition: lib_id.c:77
void(* IDTypeForeachCacheFunctionCallback)(struct ID *id, const struct IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data)
Definition: BKE_idtype.h:77
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3231
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
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
Definition: BLI_sys_types.h:67
#define ARRAY_SIZE(arr)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_DEFAULT
ID and Library types, which are fundamental for sdna.
@ INDEX_ID_NULL
Definition: DNA_ID.h:1057
@ INDEX_ID_MAX
Definition: DNA_ID.h:1058
ID_Type
Definition: DNA_ID_enums.h:44
@ ID_WM
Definition: DNA_ID_enums.h:72
@ ID_CA
Definition: DNA_ID_enums.h:56
@ ID_AR
Definition: DNA_ID_enums.h:66
@ ID_MC
Definition: DNA_ID_enums.h:73
@ ID_CF
Definition: DNA_ID_enums.h:78
@ ID_LI
Definition: DNA_ID_enums.h:46
@ ID_TE
Definition: DNA_ID_enums.h:52
@ ID_IM
Definition: DNA_ID_enums.h:53
@ ID_VO
Definition: DNA_ID_enums.h:83
@ ID_WS
Definition: DNA_ID_enums.h:79
@ ID_NT
Definition: DNA_ID_enums.h:68
@ ID_LA
Definition: DNA_ID_enums.h:55
@ ID_KE
Definition: DNA_ID_enums.h:58
@ ID_TXT
Definition: DNA_ID_enums.h:62
@ ID_SO
Definition: DNA_ID_enums.h:64
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_LS
Definition: DNA_ID_enums.h:75
@ ID_MSK
Definition: DNA_ID_enums.h:74
@ ID_GD
Definition: DNA_ID_enums.h:71
@ ID_CV
Definition: DNA_ID_enums.h:81
@ ID_PAL
Definition: DNA_ID_enums.h:76
@ ID_BR
Definition: DNA_ID_enums.h:69
@ ID_LP
Definition: DNA_ID_enums.h:80
@ ID_WO
Definition: DNA_ID_enums.h:59
@ ID_SIM
Definition: DNA_ID_enums.h:84
@ ID_MA
Definition: DNA_ID_enums.h:51
@ ID_AC
Definition: DNA_ID_enums.h:67
@ ID_SCR
Definition: DNA_ID_enums.h:60
@ ID_CU_LEGACY
Definition: DNA_ID_enums.h:49
@ ID_VF
Definition: DNA_ID_enums.h:61
@ ID_ME
Definition: DNA_ID_enums.h:48
@ ID_IP
Definition: DNA_ID_enums.h:57
@ ID_GR
Definition: DNA_ID_enums.h:65
@ ID_SPK
Definition: DNA_ID_enums.h:63
@ ID_MB
Definition: DNA_ID_enums.h:50
@ ID_LT
Definition: DNA_ID_enums.h:54
@ ID_OB
Definition: DNA_ID_enums.h:47
@ ID_PA
Definition: DNA_ID_enums.h:70
@ ID_PT
Definition: DNA_ID_enums.h:82
@ ID_PC
Definition: DNA_ID_enums.h:77
#define ID_LINK_PLACEHOLDER
Definition: DNA_ID_enums.h:88
Object groups, one object can be in many groups at once.
Read Guarded memory(de)allocation.
#define BR
Definition: boxpack_2d.c:84
Scene scene
void * user_data
const char * BKE_idtype_idcode_to_name_plural(const short idcode)
Definition: idtype.c:149
#define INIT_TYPE(_id_code)
#define CASE_IDINDEX(_id)
#define CASE_IDCODE(_id)
short BKE_idtype_idcode_from_idfilter(const uint64_t idfilter)
Definition: idtype.c:266
const IDTypeInfo * BKE_idtype_get_info_from_id(const ID *id)
Definition: idtype.c:124
const char * BKE_idtype_idcode_to_translation_context(const short idcode)
Definition: idtype.c:156
bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v)
Definition: idtype.c:39
short BKE_idtype_idcode_from_index(const int index)
Definition: idtype.c:383
#define CASE_IDFILTER_NONE(_id)
bool BKE_idtype_idcode_is_only_appendable(const short idcode)
Definition: idtype.c:182
bool BKE_idtype_idcode_is_linkable(const short idcode)
Definition: idtype.c:175
bool BKE_idtype_idcode_is_valid(const short idcode)
Definition: idtype.c:170
static const IDTypeInfo * idtype_get_info_from_name(const char *idtype_name)
Definition: idtype.c:129
#define CASE_IDFILTER(_id)
void BKE_idtype_id_foreach_cache(struct ID *id, IDTypeForeachCacheFunctionCallback function_callback, void *user_data)
Definition: idtype.c:447
short BKE_idtype_idcode_iter_step(int *index)
Definition: idtype.c:442
const char * BKE_idtype_idcode_to_name(const short idcode)
Definition: idtype.c:142
const IDTypeInfo * BKE_idtype_get_info_from_idcode(const short id_code)
Definition: idtype.c:112
short BKE_idtype_idcode_from_name(const char *idtype_name)
Definition: idtype.c:163
static void id_type_init(void)
Definition: idtype.c:49
bool BKE_idtype_idcode_append_is_reusable(const short idcode)
Definition: idtype.c:194
static IDTypeInfo * id_types[INDEX_ID_MAX]
Definition: idtype.c:47
int BKE_idtype_idcode_to_index(const short idcode)
Definition: idtype.c:324
uint BKE_idtype_cache_key_hash(const void *key_v)
Definition: idtype.c:31
uint64_t BKE_idtype_idcode_to_idfilter(const short idcode)
Definition: idtype.c:206
void BKE_idtype_init(void)
Definition: idtype.c:106
#define GS(x)
Definition: iris.c:225
#define LT
#define CV
#define hash
Definition: noise.c:153
unsigned __int64 uint64_t
Definition: stdint.h:90
unsigned int id_session_uuid
Definition: BKE_idtype.h:46
size_t offset_in_ID
Definition: BKE_idtype.h:49
int main_listbase_index
Definition: BKE_idtype.h:126
short id_code
Definition: BKE_idtype.h:114
const char * name
Definition: BKE_idtype.h:132
const char * name_plural
Definition: BKE_idtype.h:134
IDTypeForeachCacheFunction foreach_cache
Definition: BKE_idtype.h:179
uint32_t flags
Definition: BKE_idtype.h:139
const char * translation_context
Definition: BKE_idtype.h:136
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
struct Collection * master_collection