Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/library_remap.c
| Show First 20 Lines • Show All 724 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void BKE_libblock_free_data(ID *id, const bool do_id_user) | void BKE_libblock_free_data(ID *id, const bool do_id_user) | ||||
| { | { | ||||
| if (id->properties) { | if (id->properties) { | ||||
| IDP_FreeProperty_ex(id->properties, do_id_user); | IDP_FreeProperty_ex(id->properties, do_id_user); | ||||
| MEM_freeN(id->properties); | 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); | const short type = GS(id->name); | ||||
| switch (type) { | switch (type) { | ||||
| case ID_SCE: | case ID_SCE: | ||||
| BKE_scene_free((Scene *)id); | BKE_scene_free((Scene *)id); | ||||
| break; | break; | ||||
| case ID_LI: | case ID_LI: | ||||
| BKE_library_free((Library *)id); | BKE_library_free((Library *)id); | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | case ID_PC: | ||||
| BKE_paint_curve_free((PaintCurve *)id); | BKE_paint_curve_free((PaintCurve *)id); | ||||
| break; | break; | ||||
| case ID_CF: | case ID_CF: | ||||
| BKE_cachefile_free((CacheFile *)id); | BKE_cachefile_free((CacheFile *)id); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| 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 | * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c | ||||
| * | * | ||||
| * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv. | * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv. | ||||
| * (only applies to main database) | * (only applies to main database) | ||||
| * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to | * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to | ||||
| * \a id. | * \a id. | ||||
| */ | */ | ||||
| void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) | void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) | ||||
| { | { | ||||
| ID *id = idv; | ID *id = idv; | ||||
| short type = GS(id->name); | short type = GS(id->name); | ||||
| ListBase *lb = which_libbase(bmain, type); | ListBase *lb = which_libbase(bmain, type); | ||||
| DAG_id_type_tag(bmain, type); | DAG_id_type_tag(bmain, type); | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| BPY_id_release(id); | BPY_id_release(id); | ||||
| #endif | #endif | ||||
| if (do_id_user) { | if (do_id_user) { | ||||
| BKE_libblock_relink_ex(bmain, id, NULL, NULL, true); | 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 */ | /* avoid notifying on removed data */ | ||||
| BKE_main_lock(bmain); | BKE_main_lock(bmain); | ||||
| if (do_ui_user) { | if (do_ui_user) { | ||||
| if (free_notifier_reference_cb) { | if (free_notifier_reference_cb) { | ||||
| free_notifier_reference_cb(id); | free_notifier_reference_cb(id); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 93 Lines • Show Last 20 Lines | |||||