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) */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs