Blender  V3.3
lib_id_remapper.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2022 Blender Foundation. */
3 
4 #include "DNA_ID.h"
5 
6 #include "BKE_idtype.h"
7 #include "BKE_lib_id.h"
8 #include "BKE_lib_remap.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_map.hh"
13 
15 
17 struct IDRemapper {
18  private:
19  Map<ID *, ID *> mappings;
20  IDTypeFilter source_types = 0;
21 
22  public:
23  void clear()
24  {
25  mappings.clear();
26  source_types = 0;
27  }
28 
29  bool is_empty() const
30  {
31  return mappings.is_empty();
32  }
33 
34  void add(ID *old_id, ID *new_id)
35  {
36  BLI_assert(old_id != nullptr);
37  BLI_assert(new_id == nullptr || (GS(old_id->name) == GS(new_id->name)));
38  mappings.add(old_id, new_id);
40  source_types |= BKE_idtype_idcode_to_idfilter(GS(old_id->name));
41  }
42 
44  {
45  return (source_types & filter) != 0;
46  }
47 
50  const ID *id_self) const
51  {
52  if (!mappings.contains(id)) {
54  }
55  const ID *new_id = mappings.lookup(id);
56  if ((options & ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF) != 0 && id_self == new_id) {
57  new_id = nullptr;
58  }
59  if (new_id == nullptr) {
61  }
62 
64  }
65 
67  {
68  BLI_assert(r_id_ptr != nullptr);
69  if (*r_id_ptr == nullptr) {
71  }
72 
73  if (!mappings.contains(*r_id_ptr)) {
75  }
76 
78  id_us_min(*r_id_ptr);
79  }
80 
81  *r_id_ptr = mappings.lookup(*r_id_ptr);
82  if (options & ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF && *r_id_ptr == id_self) {
83  *r_id_ptr = nullptr;
84  }
85  if (*r_id_ptr == nullptr) {
87  }
88 
90  /* Do not handle LIB_TAG_INDIRECT/LIB_TAG_EXTERN here. */
91  id_us_plus_no_lib(*r_id_ptr);
92  }
93 
95  id_us_ensure_real(*r_id_ptr);
96  }
98  }
99 
100  void iter(IDRemapperIterFunction func, void *user_data) const
101  {
102  for (auto item : mappings.items()) {
103  func(item.key, item.value, user_data);
104  }
105  }
106 };
107 
108 } // namespace blender::bke::id::remapper
109 
111 static IDRemapper *wrap(blender::bke::id::remapper::IDRemapper *remapper)
112 {
113  return static_cast<IDRemapper *>(static_cast<void *>(remapper));
114 }
115 
117 static blender::bke::id::remapper::IDRemapper *unwrap(IDRemapper *remapper)
118 {
119  return static_cast<blender::bke::id::remapper::IDRemapper *>(static_cast<void *>(remapper));
120 }
121 
123 static const blender::bke::id::remapper::IDRemapper *unwrap(const IDRemapper *remapper)
124 {
125  return static_cast<const blender::bke::id::remapper::IDRemapper *>(
126  static_cast<const void *>(remapper));
127 }
128 
129 extern "C" {
130 
131 IDRemapper *BKE_id_remapper_create(void)
132 {
134  MEM_new<blender::bke::id::remapper::IDRemapper>(__func__);
135  return wrap(remapper);
136 }
137 
138 void BKE_id_remapper_free(IDRemapper *id_remapper)
139 {
140  blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
141  MEM_delete<blender::bke::id::remapper::IDRemapper>(remapper);
142 }
143 
144 void BKE_id_remapper_clear(struct IDRemapper *id_remapper)
145 {
146  blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
147  remapper->clear();
148 }
149 
150 bool BKE_id_remapper_is_empty(const struct IDRemapper *id_remapper)
151 {
152  const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
153  return remapper->is_empty();
154 }
155 
156 void BKE_id_remapper_add(IDRemapper *id_remapper, ID *old_id, ID *new_id)
157 {
158  blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
159  remapper->add(old_id, new_id);
160 }
161 
162 bool BKE_id_remapper_has_mapping_for(const struct IDRemapper *id_remapper, uint64_t type_filter)
163 {
164  const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
165  return remapper->contains_mappings_for_any(type_filter);
166 }
167 
168 IDRemapperApplyResult BKE_id_remapper_get_mapping_result(const struct IDRemapper *id_remapper,
169  struct ID *id,
171  const struct ID *id_self)
172 {
173  const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
174  return remapper->get_mapping_result(id, options, id_self);
175 }
176 
177 IDRemapperApplyResult BKE_id_remapper_apply_ex(const IDRemapper *id_remapper,
178  ID **r_id_ptr,
180  ID *id_self)
181 {
183  id_self != nullptr,
184  "ID_REMAP_APPLY_WHEN_REMAPPING_TO_SELF requires id_self parameter.");
185  const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
186  return remapper->apply(r_id_ptr, options, id_self);
187 }
188 
189 IDRemapperApplyResult BKE_id_remapper_apply(const IDRemapper *id_remapper,
190  ID **r_id_ptr,
192 {
194  "ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF requires id_self parameter. Use "
195  "`BKE_id_remapper_apply_ex`.");
196  return BKE_id_remapper_apply_ex(id_remapper, r_id_ptr, options, nullptr);
197 }
198 
199 void BKE_id_remapper_iter(const struct IDRemapper *id_remapper,
201  void *user_data)
202 {
203  const blender::bke::id::remapper::IDRemapper *remapper = unwrap(id_remapper);
204  remapper->iter(func, user_data);
205 }
206 
208 {
209  switch (result) {
211  return "not_mappable";
213  return "unavailable";
215  return "unassigned";
217  return "remapped";
218  default:
220  }
221  return "";
222 }
223 
224 static void id_remapper_print_item_cb(ID *old_id, ID *new_id, void *UNUSED(user_data))
225 {
226  if (old_id != nullptr && new_id != nullptr) {
227  printf("Remap %s(%p) to %s(%p)\n", old_id->name, old_id, new_id->name, new_id);
228  }
229  if (old_id != nullptr && new_id == nullptr) {
230  printf("Unassign %s(%p)\n", old_id->name, old_id);
231  }
232 }
233 
234 void BKE_id_remapper_print(const struct IDRemapper *id_remapper)
235 {
236  BKE_id_remapper_iter(id_remapper, id_remapper_print_item_cb, nullptr);
237 }
238 }
uint64_t BKE_idtype_idcode_to_idfilter(short idcode)
Definition: idtype.c:206
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_ensure_real(struct ID *id)
Definition: lib_id.c:260
void id_us_plus_no_lib(struct ID *id)
Definition: lib_id.c:289
IDRemapperApplyResult
@ ID_REMAP_RESULT_SOURCE_REMAPPED
@ ID_REMAP_RESULT_SOURCE_UNASSIGNED
@ ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE
@ ID_REMAP_RESULT_SOURCE_UNAVAILABLE
IDRemapperApplyOptions
@ ID_REMAP_APPLY_UPDATE_REFCOUNT
@ ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF
@ ID_REMAP_APPLY_ENSURE_REAL
void(* IDRemapperIterFunction)(struct ID *old_id, struct ID *new_id, void *user_data)
#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
#define UNUSED(x)
ID and Library types, which are fundamental for sdna.
Read Guarded memory(de)allocation.
void clear()
Definition: BLI_map.hh:963
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:250
const Value & lookup(const Key &key) const
Definition: BLI_map.hh:485
ItemIterator items() const
Definition: BLI_map.hh:859
bool is_empty() const
Definition: BLI_map.hh:911
bool contains(const Key &key) const
Definition: BLI_map.hh:308
CCL_NAMESPACE_BEGIN struct Options options
void * user_data
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
#define GS(x)
Definition: iris.c:225
void BKE_id_remapper_add(IDRemapper *id_remapper, ID *old_id, ID *new_id)
static void id_remapper_print_item_cb(ID *old_id, ID *new_id, void *UNUSED(user_data))
static blender::bke::id::remapper::IDRemapper * unwrap(IDRemapper *remapper)
wrap C handle to a CPP IDRemapper.
bool BKE_id_remapper_has_mapping_for(const struct IDRemapper *id_remapper, uint64_t type_filter)
IDRemapperApplyResult BKE_id_remapper_get_mapping_result(const struct IDRemapper *id_remapper, struct ID *id, IDRemapperApplyOptions options, const struct ID *id_self)
static IDRemapper * wrap(blender::bke::id::remapper::IDRemapper *remapper)
wrap CPP IDRemapper to a C handle.
void BKE_id_remapper_clear(struct IDRemapper *id_remapper)
uint64_t IDTypeFilter
IDRemapper * BKE_id_remapper_create(void)
IDRemapperApplyResult BKE_id_remapper_apply_ex(const IDRemapper *id_remapper, ID **r_id_ptr, const IDRemapperApplyOptions options, ID *id_self)
const char * BKE_id_remapper_result_string(const IDRemapperApplyResult result)
void BKE_id_remapper_print(const struct IDRemapper *id_remapper)
bool BKE_id_remapper_is_empty(const struct IDRemapper *id_remapper)
void BKE_id_remapper_iter(const struct IDRemapper *id_remapper, IDRemapperIterFunction func, void *user_data)
IDRemapperApplyResult BKE_id_remapper_apply(const IDRemapper *id_remapper, ID **r_id_ptr, const IDRemapperApplyOptions options)
void BKE_id_remapper_free(IDRemapper *id_remapper)
unsigned __int64 uint64_t
Definition: stdint.h:90
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
void add(ID *old_id, ID *new_id)
void iter(IDRemapperIterFunction func, void *user_data) const
bool contains_mappings_for_any(IDTypeFilter filter) const
IDRemapperApplyResult get_mapping_result(ID *id, IDRemapperApplyOptions options, const ID *id_self) const
IDRemapperApplyResult apply(ID **r_id_ptr, IDRemapperApplyOptions options, ID *id_self) const