[Bf-blender-cvs] [23941b425ed] id_copy_refactor: Add same new ID freeing API as copying one.
Bastien Montagne
noreply at git.blender.org
Fri Jun 16 10:51:25 CEST 2017
Commit: 23941b425ed9a7243a7b91b8c9a216de9f636bca
Author: Bastien Montagne
Date: Thu Jun 15 16:18:48 2017 +0200
Branches: id_copy_refactor
https://developer.blender.org/rB23941b425ed9a7243a7b91b8c9a216de9f636bca
Add same new ID freeing API as copying one.
Idea is the same, looks like it will be a tad simpler than with copy
though, since we should not need to change each ID type freeing func, as
ID usercount handling is done in main BKE_library code (would like to do
that for copy as well, but it's not that simple).
===================================================================
M source/blender/blenkernel/BKE_library.h
M source/blender/blenkernel/intern/library.c
M source/blender/blenkernel/intern/library_remap.c
M source/blender/blenloader/intern/writefile.c
M source/blender/makesdna/DNA_ID.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 4273aafd7d8..6a67188b640 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -62,10 +62,14 @@ enum {
/* *** Generic options (should be handled by all ID types copying). *** */
/* Create copy outside of any main database - similar to 'localize' functions of materials etc. */
LIB_ID_COPY_NO_MAIN = 1 << 0,
- LIB_ID_COPY_NO_USER_REFCOUNT = 1 << 1, /* Do not affect user refcount of datablocks used by copied one. */
- LIB_ID_COPY_NO_DEG_TAG = 1 << 2, /* Do not tag duplicated ID for update in depsgraph. */
- /* Assume given 'newid' already points to allocated memory for whole datablock (ID + data) - USE WITH CAUTION! */
- LIB_ID_COPY_NO_ALLOCATE = 1 << 3,
+ /* Do not affect user refcount of datablocks used by copied one.
+ * Implies LIB_ID_COPY_NO_MAIN. */
+ LIB_ID_COPY_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume given 'newid' already points to allocated memory for whole datablock (ID + data) - USE WITH CAUTION!
+ * Implies LIB_ID_COPY_NO_MAIN. */
+ LIB_ID_COPY_NO_ALLOCATE = 1 << 2,
+
+ LIB_ID_COPY_NO_DEG_TAG = 1 << 8, /* Do not tag duplicated ID for update in depsgraph. */
/* Specific options to some ID types or usages, may be ignored by unrelated ID copying functions. */
LIB_ID_COPY_NO_PROXY_CLEAR = 1 << 16, /* Object only, needed by make_local code. */
@@ -77,7 +81,9 @@ enum {
void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+/* "Deprecated" old API. */
void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL();
+
void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL();
@@ -87,13 +93,39 @@ struct ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const
struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* library_remap.c (keep here since they're general functions) */
-void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL();
+/**
+ * New freeing logic options.
+ */
+enum {
+ /* *** Generic options (should be handled by all ID types freeing). *** */
+ /* Do not try to remove freed ID from given Main (passed Main may be NULL). */
+ LIB_ID_FREE_NO_MAIN = 1 << 0,
+ /* Do not affect user refcount of datablocks used by freed one.
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume freed ID datablock memory is managed elsewhere, do not free it
+ * (still calls relevant ID type's freeing function though) - USE WITH CAUTION!
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NOT_ALLOCATED = 1 << 2,
+
+ LIB_ID_FREE_NO_DEG_TAG = 1 << 8, /* Do not tag freed ID for update in depsgraph. */
+ LIB_ID_FREE_NO_UI_USER = 1 << 9, /* Do not attempt to remove freed ID from UI data/notifiers/... */
+};
+
+void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, const bool use_flag_from_idtag);
+void BKE_id_free(struct Main *bmain, void *idv);
+/* Those three naming are bad actually, should be BKE_id_free... (since it goes beyond mere datablock). */
+/* "Deprecated" old API */
void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
+void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
+/* TODO should be named "BKE_id_delete()". */
void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_free_datablock(struct ID *id, const int flag) ATTR_NONNULL();
+void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index a1d0f12bed3..a0c1bc93f6b 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1127,7 +1127,8 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla
ID *idn = *r_newid;
BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || bmain != NULL);
- BLI_assert((flag & LIB_ID_COPY_NO_ALLOCATE) == 0 || (flag & LIB_ID_COPY_NO_MAIN) != 0);
+ BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || (flag & LIB_ID_COPY_NO_ALLOCATE) == 0);
+ BLI_assert((flag & LIB_ID_COPY_NO_MAIN) != 0 || (flag & LIB_ID_COPY_NO_USER_REFCOUNT) == 0);
if ((flag & LIB_ID_COPY_NO_ALLOCATE) != 0) {
/* r_newid already contains pointer to allocated memory. */
@@ -1166,7 +1167,7 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla
idn->tag |= LIB_TAG_FREE_NO_USER_REFCOUNT;
}
if ((flag & LIB_ID_COPY_NO_ALLOCATE) != 0) {
- idn->tag |= LIB_TAG_FREE_NO_ALLOCATED;
+ idn->tag |= LIB_TAG_FREE_NOT_ALLOCATED;
}
if ((flag & LIB_ID_COPY_NO_DEG_TAG) == 0 && (flag & LIB_ID_COPY_NO_MAIN) == 0) {
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 01ad4fb86ce..c11d64843f4 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -729,9 +729,11 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
IDP_FreeProperty_ex(id->properties, do_id_user);
MEM_freeN(id->properties);
}
+
+ /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */
}
-void BKE_libblock_free_datablock(ID *id)
+void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
const short type = GS(id->name);
switch (type) {
@@ -841,6 +843,90 @@ void BKE_libblock_free_datablock(ID *id)
}
}
+
+void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
+{
+ ID *id = idv;
+
+ if (use_flag_from_idtag) {
+ if ((id->tag & LIB_TAG_FREE_NO_MAIN) != 0) {
+ flag |= LIB_ID_FREE_NO_MAIN;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_MAIN;
+ }
+
+ if ((id->tag & LIB_TAG_FREE_NO_USER_REFCOUNT) != 0) {
+ flag |= LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+
+ if ((id->tag & LIB_TAG_FREE_NOT_ALLOCATED) != 0) {
+ flag |= LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ }
+
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ const short type = GS(id->name);
+
+ if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
+ DAG_id_type_tag(bmain, type);
+ }
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id, flag);
+
+ /* avoid notifying on removed data */
+ if (bmain) {
+ BKE_main_lock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
+ if (free_notifier_reference_cb) {
+ free_notifier_reference_cb(id);
+ }
+
+ if (remap_editor_id_reference_cb) {
+ remap_editor_id_reference_cb(id, NULL);
+ }
+ }
+
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+ BLI_remlink(lb, id);
+ }
+
+ BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ if (bmain) {
+ BKE_main_unlock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
+ MEM_freeN(id);
+ }
+}
+
+void BKE_id_free(Main *bmain, void *idv)
+{
+ BKE_id_free_ex(bmain, idv, 0, true);
+}
+
/**
* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
*
@@ -865,7 +951,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
}
- BKE_libblock_free_datablock(id);
+ BKE_libblock_free_datablock(id, 0);
/* avoid notifying on removed data */
BKE_main_lock(bmain);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0336f28ed85..fbaaa91bc4d 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3842,7 +3842,7 @@ static bool write_file_handle(
for (; id; id = id->next) {
/* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
- BLI_assert((id->tag & (LIB_TAG_FREE_NO_MAIN | LIB_TAG_FREE_NO_USER_REFCOUNT | LIB_TAG_FREE_NO_ALLOCATED)) == 0);
+ BLI_assert((id->tag & (LIB_TAG_FREE_NO_MAIN | LIB_TAG_FREE_NO_USER_REFCOUNT | LIB_TAG_FREE_NOT_ALLOCATED)) == 0);
switch ((ID_Type)GS(id->name)) {
case ID_WM:
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 857b7478481..b3690e7d179 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -355,7 +355,7 @@ enum {
LIB_TAG_FREE_NO_USER_REFCOUNT = 1 << 17, /* Datablock does not refcount usages of other IDs. */
/* Datablock was not allocated by standard system (BKE_libblock_alloc), do not free its memory
* (usual type-specific freeing is called though). */
- LIB_TAG_FREE_NO_ALLOCATED = 1 << 18,
+ LIB_TAG_FREE_NOT_ALLOCATED = 1 << 18,
};
/* To filter ID types (filter_id) */
More information about the Bf-blender-cvs
mailing list