Blender  V2.93
lib_id_delete.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
23 #include "MEM_guardedalloc.h"
24 
25 /* all types are needed here, in order to do memory operations */
26 #include "DNA_ID.h"
27 #include "DNA_key_types.h"
28 
29 #include "BLI_utildefines.h"
30 
31 #include "BLI_listbase.h"
32 
33 #include "BKE_anim_data.h"
34 #include "BKE_asset.h"
35 #include "BKE_idprop.h"
36 #include "BKE_idtype.h"
37 #include "BKE_key.h"
38 #include "BKE_lib_id.h"
39 #include "BKE_lib_override.h"
40 #include "BKE_lib_remap.h"
41 #include "BKE_library.h"
42 #include "BKE_main.h"
43 
44 #include "lib_intern.h"
45 
46 #include "DEG_depsgraph.h"
47 
48 #ifdef WITH_PYTHON
49 # include "BPY_extern.h"
50 #endif
51 
52 /* Not used currently. */
53 // static CLG_LogRef LOG = {.identifier = "bke.lib_id_delete"};
54 
55 void BKE_libblock_free_data(ID *id, const bool do_id_user)
56 {
57  if (id->properties) {
60  id->properties = NULL;
61  }
62 
63  if (id->override_library) {
65  id->override_library = NULL;
66  }
67 
68  if (id->asset_data) {
70  }
71 
72  BKE_animdata_free(id, do_id_user);
73 }
74 
75 void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
76 {
77  const IDTypeInfo *idtype_info = BKE_idtype_get_info_from_id(id);
78 
79  if (idtype_info != NULL) {
80  if (idtype_info->free_data != NULL) {
81  idtype_info->free_data(id);
82  }
83  return;
84  }
85 
86  BLI_assert(!"IDType Missing IDTypeInfo");
87 }
88 
106 void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
107 {
108  ID *id = idv;
109 
110  if (use_flag_from_idtag) {
111  if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
113  }
114  else {
115  flag &= ~LIB_ID_FREE_NO_MAIN;
116  }
117 
118  if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
120  }
121  else {
123  }
124 
125  if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
127  }
128  else {
129  flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
130  }
131  }
132 
133  BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
134  BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
135  BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
136 
137  const short type = GS(id->name);
138 
139  if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
140  BLI_assert(bmain->is_locked_for_linking == false);
141 
142  DEG_id_type_tag(bmain, type);
143  }
144 
146 
147  Key *key = ((flag & LIB_ID_FREE_NO_MAIN) == 0) ? BKE_key_from_id(id) : NULL;
148 
149  if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
150  BKE_libblock_relink_ex(bmain, id, NULL, NULL, 0);
151  }
152 
153  if ((flag & LIB_ID_FREE_NO_MAIN) == 0 && key != NULL) {
154  BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
155  }
156 
157  BKE_libblock_free_datablock(id, flag);
158 
159  /* avoid notifying on removed data */
160  if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
161  BKE_main_lock(bmain);
162  }
163 
164  if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
167  }
168 
171  }
172  }
173 
174  if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
175  ListBase *lb = which_libbase(bmain, type);
176  BLI_remlink(lb, id);
177  }
178 
180 
181  if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
182  BKE_main_unlock(bmain);
183  }
184 
185  if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
186  MEM_freeN(id);
187  }
188 }
189 
199 void BKE_id_free(Main *bmain, void *idv)
200 {
201  BKE_id_free_ex(bmain, idv, 0, true);
202 }
203 
208 void BKE_id_free_us(Main *bmain, void *idv) /* test users */
209 {
210  ID *id = idv;
211 
212  id_us_min(id);
213 
214  /* XXX This is a temp (2.77) hack so that we keep same behavior as in 2.76 regarding collections
215  * when deleting an object. Since only 'user_one' usage of objects is collections,
216  * and only 'real user' usage of objects is scenes, removing that 'user_one' tag when there
217  * is no more real (scene) users of an object ensures it gets fully unlinked.
218  * But only for local objects, not linked ones!
219  * Otherwise, there is no real way to get rid of an object anymore -
220  * better handling of this is TODO.
221  */
222  if ((GS(id->name) == ID_OB) && (id->us == 1) && (id->lib == NULL)) {
223  id_us_clear_real(id);
224  }
225 
226  if (id->us == 0) {
227  BKE_libblock_unlink(bmain, id, false, false);
228 
229  BKE_id_free(bmain, id);
230  }
231 }
232 
233 static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
234 {
235  const int tag = LIB_TAG_DOIT;
236  ListBase *lbarray[INDEX_ID_MAX];
237  Link dummy_link = {0};
238  int base_count, i;
239 
240  /* Used by batch tagged deletion, when we call BKE_id_free then, id is no more in Main database,
241  * and has already properly unlinked its other IDs usages.
242  * UI users are always cleared in BKE_libblock_remap_locked() call, so we can always skip it. */
243  const int free_flag = LIB_ID_FREE_NO_UI_USER |
244  (do_tagged_deletion ? LIB_ID_FREE_NO_MAIN | LIB_ID_FREE_NO_USER_REFCOUNT :
245  0);
246  ListBase tagged_deleted_ids = {NULL};
247 
248  base_count = set_listbasepointers(bmain, lbarray);
249 
250  BKE_main_lock(bmain);
251  if (do_tagged_deletion) {
252  /* Main idea of batch deletion is to remove all IDs to be deleted from Main database.
253  * This means that we won't have to loop over all deleted IDs to remove usages
254  * of other deleted IDs.
255  * This gives tremendous speed-up when deleting a large amount of IDs from a Main
256  * containing thousands of those.
257  * This also means that we have to be very careful here, as we by-pass many 'common'
258  * processing, hence risking to 'corrupt' at least user counts, if not IDs themselves. */
259  bool keep_looping = true;
260  while (keep_looping) {
261  ID *id, *id_next;
262  ID *last_remapped_id = tagged_deleted_ids.last;
263  keep_looping = false;
264 
265  /* First tag and remove from Main all datablocks directly from target lib.
266  * Note that we go forward here, since we want to check dependencies before users
267  * (e.g. meshes before objects). Avoids to have to loop twice. */
268  for (i = 0; i < base_count; i++) {
269  ListBase *lb = lbarray[i];
270 
271  for (id = lb->first; id; id = id_next) {
272  id_next = id->next;
273  /* Note: in case we delete a library, we also delete all its datablocks! */
274  if ((id->tag & tag) || (id->lib != NULL && (id->lib->id.tag & tag))) {
275  BLI_remlink(lb, id);
276  BLI_addtail(&tagged_deleted_ids, id);
277  /* Do not tag as no_main now, we want to unlink it first (lower-level ID management
278  * code has some specific handling of 'no main' IDs that would be a problem in that
279  * case). */
280  id->tag |= tag;
281  keep_looping = true;
282  }
283  }
284  }
285  if (last_remapped_id == NULL) {
286  dummy_link.next = tagged_deleted_ids.first;
287  last_remapped_id = (ID *)(&dummy_link);
288  }
289  for (id = last_remapped_id->next; id; id = id->next) {
290  /* Will tag 'never NULL' users of this ID too.
291  * Note that we cannot use BKE_libblock_unlink() here,
292  * since it would ignore indirect (and proxy!)
293  * links, this can lead to nasty crashing here in second, actual deleting loop.
294  * Also, this will also flag users of deleted data that cannot be unlinked
295  * (object using deleted obdata, etc.), so that they also get deleted. */
297  id,
298  NULL,
302  /* Since we removed ID from Main,
303  * we also need to unlink its own other IDs usages ourself. */
305  }
306  }
307 
308  /* Now we can safely mark that ID as not being in Main database anymore. */
309  /* NOTE: This needs to be done in a separate loop than above, otherwise some usercounts of
310  * deleted IDs may not be properly decreased by the remappings (since `NO_MAIN` ID usercounts
311  * is never affected). */
312  for (ID *id = tagged_deleted_ids.first; id; id = id->next) {
313  id->tag |= LIB_TAG_NO_MAIN;
314  }
315  }
316  else {
317  /* First tag all datablocks directly from target lib.
318  * Note that we go forward here, since we want to check dependencies before users
319  * (e.g. meshes before objects).
320  * Avoids to have to loop twice. */
321  for (i = 0; i < base_count; i++) {
322  ListBase *lb = lbarray[i];
323  ID *id, *id_next;
324 
325  for (id = lb->first; id; id = id_next) {
326  id_next = id->next;
327  /* Note: in case we delete a library, we also delete all its datablocks! */
328  if ((id->tag & tag) || (id->lib != NULL && (id->lib->id.tag & tag))) {
329  id->tag |= tag;
330 
331  /* Will tag 'never NULL' users of this ID too.
332  * Note that we cannot use BKE_libblock_unlink() here, since it would ignore indirect
333  * (and proxy!) links, this can lead to nasty crashing here in second,
334  * actual deleting loop.
335  * Also, this will also flag users of deleted data that cannot be unlinked
336  * (object using deleted obdata, etc.), so that they also get deleted. */
338  id,
339  NULL,
343  }
344  }
345  }
346  }
347  BKE_main_unlock(bmain);
348 
349  /* In usual reversed order, such that all usage of a given ID, even 'never NULL' ones,
350  * have been already cleared when we reach it
351  * (e.g. Objects being processed before meshes, they'll have already released their 'reference'
352  * over meshes when we come to freeing obdata). */
353  size_t num_datablocks_deleted = 0;
354  for (i = do_tagged_deletion ? 1 : base_count; i--;) {
355  ListBase *lb = lbarray[i];
356  ID *id, *id_next;
357 
358  for (id = do_tagged_deletion ? tagged_deleted_ids.first : lb->first; id; id = id_next) {
359  id_next = id->next;
360  if (id->tag & tag) {
361  if (id->us != 0) {
362 #ifdef DEBUG_PRINT
363  printf("%s: deleting %s (%d)\n", __func__, id->name, id->us);
364 #endif
365  BLI_assert(id->us == 0);
366  }
367  BKE_id_free_ex(bmain, id, free_flag, !do_tagged_deletion);
368  ++num_datablocks_deleted;
369  }
370  }
371  }
372 
373  bmain->is_memfile_undo_written = false;
374  return num_datablocks_deleted;
375 }
376 
380 void BKE_id_delete(Main *bmain, void *idv)
381 {
382  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
383  ((ID *)idv)->tag |= LIB_TAG_DOIT;
384 
385  id_delete(bmain, false);
386 }
387 
399 {
400  return id_delete(bmain, true);
401 }
402 
403 /* -------------------------------------------------------------------- */
414 {
415 #ifdef WITH_PYTHON
416 # ifdef WITH_PYTHON_SAFETY
417  BPY_id_release(id);
418 # endif
419  if (id->py_instance) {
421  }
422 #else
423  UNUSED_VARS(id);
424 #endif
425 }
426 
void BKE_animdata_free(struct ID *id, const bool do_id_user)
Definition: anim_data.c:230
void BKE_asset_metadata_free(struct AssetMetaData **asset_data)
Definition: asset.cc:47
void IDP_FreePropertyContent_ex(struct IDProperty *prop, const bool do_id_user)
Definition: idprop.c:1006
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
struct Key * BKE_key_from_id(struct ID *id)
Definition: key.c:1786
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value)
Definition: lib_id.c:923
@ LIB_ID_FREE_NO_UI_USER
Definition: BKE_lib_id.h:204
@ LIB_ID_FREE_NOT_ALLOCATED
Definition: BKE_lib_id.h:199
@ LIB_ID_FREE_NO_DEG_TAG
Definition: BKE_lib_id.h:202
@ LIB_ID_FREE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:193
@ LIB_ID_FREE_NO_MAIN
Definition: BKE_lib_id.h:188
void id_us_clear_real(struct ID *id)
Definition: lib_id.c:257
void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bool do_id_user)
Definition: lib_override.c:182
void void void BKE_libblock_unlink(struct Main *bmain, void *idv, const bool do_flag_never_null, const bool do_skip_indirect) ATTR_NONNULL()
Definition: lib_remap.c:573
void BKE_libblock_relink_ex(struct Main *bmain, void *idv, void *old_idv, void *new_idv, const short remap_flags) ATTR_NONNULL(1
@ ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS
Definition: BKE_lib_remap.h:87
@ ID_REMAP_FLAG_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:60
@ ID_REMAP_FORCE_NEVER_NULL_USAGE
Definition: BKE_lib_remap.h:67
void BKE_libblock_remap_locked(struct Main *bmain, void *old_idv, void *new_idv, const short remap_flags) ATTR_NONNULL(1
int set_listbasepointers(struct Main *main, struct ListBase *lb[])
void BKE_main_unlock(struct Main *bmain)
Definition: main.c:207
void BKE_main_lock(struct Main *bmain)
Definition: main.c:202
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:447
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
#define UNUSED_VARS(...)
#define UNUSED(x)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
void BPY_id_release(struct ID *id)
Definition: bpy_rna.c:306
void DEG_id_type_tag(struct Main *bmain, short id_type)
ID and Library types, which are fundamental for sdna.
@ LIB_TAG_NO_USER_REFCOUNT
Definition: DNA_ID.h:573
@ LIB_TAG_NOT_ALLOCATED
Definition: DNA_ID.h:576
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:572
@ INDEX_ID_MAX
Definition: DNA_ID.h:859
@ ID_OB
Definition: DNA_ID_enums.h:59
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define GS(x)
Definition: iris.c:241
static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
Definition: lib_id_delete.c:75
size_t BKE_id_multi_tagged_delete(Main *bmain)
void BKE_libblock_free_data_py(ID *id)
void BKE_id_free(Main *bmain, void *idv)
void BKE_libblock_free_data(ID *id, const bool do_id_user)
Definition: lib_id_delete.c:55
void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
void BKE_id_free_us(Main *bmain, void *idv)
void BKE_id_delete(Main *bmain, void *idv)
BKE_library_remap_editor_id_reference_cb remap_editor_id_reference_cb
Definition: lib_remap.c:59
BKE_library_free_notifier_reference_cb free_notifier_reference_cb
Definition: lib_remap.c:52
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
IDTypeFreeDataFunction free_data
Definition: BKE_idtype.h:167
Definition: DNA_ID.h:273
void * py_instance
Definition: DNA_ID.h:340
int tag
Definition: DNA_ID.h:292
struct AssetMetaData * asset_data
Definition: DNA_ID.h:280
struct Library * lib
Definition: DNA_ID.h:277
int us
Definition: DNA_ID.h:293
IDProperty * properties
Definition: DNA_ID.h:314
IDOverrideLibrary * override_library
Definition: DNA_ID.h:317
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
ID id
Definition: DNA_key_types.h:79
ID id
Definition: DNA_ID.h:349
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
char is_locked_for_linking
Definition: BKE_main.h:141
char is_memfile_undo_written
Definition: BKE_main.h:125