[Bf-blender-cvs] [9584c88] id-remap: Fix a bunch of more stuff, more correct handling of ID/Lib deletion...
Bastien Montagne
noreply at git.blender.org
Thu Dec 3 16:36:52 CET 2015
Commit: 9584c88b6b482157eb6238f9690ea259c663b175
Author: Bastien Montagne
Date: Tue Dec 1 21:37:25 2015 +0100
Branches: id-remap
https://developer.blender.org/rB9584c88b6b482157eb6238f9690ea259c663b175
Fix a bunch of more stuff, more correct handling of ID/Lib deletion...
Still have some usercount issues here, though things seems to start working...
===================================================================
M source/blender/blenkernel/BKE_library.h
M source/blender/blenkernel/intern/blender.c
M source/blender/blenkernel/intern/library.c
M source/blender/blenkernel/intern/library_query.c
M source/blender/editors/object/object_group.c
M source/blender/editors/screen/screen_edit.c
M source/blender/editors/space_outliner/outliner_edit.c
M source/blender/editors/space_outliner/outliner_tools.c
M source/blender/makesrna/intern/rna_ID.c
M source/blender/makesrna/intern/rna_main_api.c
M source/blender/render/intern/source/pipeline.c
M source/blender/windowmanager/intern/wm_operators.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 8381394..fb9f443 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -60,11 +60,11 @@ void BKE_libblock_relink(struct ID *id);
/* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */
void BKE_libblock_remap_locked(
- struct Main *bmain, void *old_id, void *new_id, const bool skip_indirect_usage) ATTR_NONNULL(1, 2);
+ struct Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
void BKE_libblock_remap(
- struct Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage) ATTR_NONNULL(1, 2);
+ struct Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
-void BKE_libblock_unlink(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_unlink(struct Main *bmain, void *idv, const bool do_flag_never_null) ATTR_NONNULL();
void BKE_libblock_relink_ex(void *idv, void *old_idv, void *new_idv, const bool us_min_never_null) ATTR_NONNULL(1);
@@ -91,10 +91,11 @@ struct ListBase *which_libbase(struct Main *mainlib, short type);
int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
void BKE_libblock_free(struct Main *bmain, void *idv);
-void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool use_recursive_delete);
+void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user);
void BKE_libblock_free_us(struct Main *bmain, void *idv);
void BKE_libblock_free_data(struct Main *bmain, struct ID *id);
+void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
/* Main API */
struct Main *BKE_main_new(void);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 3288496..fc76c29 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -565,9 +565,9 @@ bool BKE_read_file_from_memfile(
if (bfd) {
/* remove the unused screens and wm */
while (bfd->main->wm.first)
- BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, true, false);
+ BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, true);
while (bfd->main->screen.first)
- BKE_libblock_free_ex(bfd->main, bfd->main->screen.first, true, false);
+ BKE_libblock_free_ex(bfd->main, bfd->main->screen.first, true);
setup_app_data(C, bfd, "<memory1>");
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 614e351..a975a06 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1044,6 +1044,9 @@ enum {
* will still be decremented. This is mandatory for 'delete ID' case, but in all other situation this would lead
* to invalid user counts! */
ID_REMAP_SKIP_NEVER_NULL_USAGE = 1 << 1,
+ /* This tells the callback func to flag with LIB_DOIT all IDs using target one with a 'never NULL' pointer
+ * (like e.g. Object->data). */
+ ID_REMAP_FLAG_NEVER_NULL_USAGE = 1 << 2,
};
/* IDRemp->status */
@@ -1070,13 +1073,17 @@ static bool foreach_libblock_remap_callback(void *user_data, ID **id_p, int cb_f
* on the other hand since they get reset to lib data on file open/reload it is indirect too...
* Edit Mode is also a 'skip direct' case. */
const bool is_obj = (GS(id->name) == ID_OB);
- const bool is_proxy = (is_obj && (((Object *)id)->proxy || ((Object *)id)->proxy_group));
+ const bool is_proxy = false; //(is_obj && (((Object *)id)->proxy || ((Object *)id)->proxy_group));
const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id));
const bool is_indirect = (id->lib != NULL);
const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
const bool is_never_null = ((cb_flag & IDWALK_NEVER_NULL) && (new_id == NULL));
const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0;
+ if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_NEVER_NULL)) {
+ id->flag |= LIB_DOIT;
+ }
+
// if (GS(old_id->name) == ID_AC)
// printf("\t\tIn %s (%p): remapping %s (%p) to %s (%p)\n",
// id->name, id, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id);
@@ -1211,19 +1218,50 @@ static void libblock_remap_data(
// r_id_remap_data->skipped_direct, r_id_remap_data->skipped_indirect);
}
-/** Replace all references in .blend file to \a old_id by \a new_id (if \a new_id is NULL, it unlinks \a old_id). */
-void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage)
+/**
+ * Replace all references in given Main to \a old_id by \a new_id (if \a new_id is NULL, it unlinks \a old_id).
+ *
+ * \param skip_indirect_usage If \a true, indirect usages (like e.g. by other linked datablocks) are not remapped.
+ * \param do_flag_never_null If \a true, 'NEVER_NULL' ID users are flagged with LIB_DOIT (caller is expected
+ * to ensure that flag is correctly unset first).
+ */
+void BKE_libblock_remap_locked(
+ Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null)
{
IDRemap id_remap_data;
ID *old_id = old_idv;
ID *new_id = new_idv;
- int remap_flags = skip_indirect_usage ? ID_REMAP_SKIP_INDIRECT_USAGE : 0;
+ int remap_flags = ((skip_indirect_usage ? ID_REMAP_SKIP_INDIRECT_USAGE : 0) |
+ (do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE : 0));
int skipped_direct, skipped_refcounted;
BLI_assert(old_id != NULL);
BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name));
BLI_assert(old_id != new_id);
+ /* Some pre-process updates.
+ * This is a bit ugly, but cannot see a way to avoid it. Maybe we should do a per-ID callback for this instead?
+ */
+ if (GS(old_id->name) == ID_OB) {
+ Object *old_ob = (Object *)old_id;
+ Object *new_ob = (Object *)new_id;
+
+ if (new_ob == NULL) {
+ Scene *sce;
+ Base *base;
+
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
+ base = BKE_scene_base_find(sce, old_ob);
+
+ if (base) {
+ id_us_min((ID *)base->object);
+ BKE_scene_base_unlink(sce, base);
+ MEM_freeN(base);
+ }
+ }
+ }
+ }
+
// if (GS(old_id->name) == ID_AC) {
// printf("%s: START %s (%p, %d) replaced by %s (%p, %d)\n",
// __func__, old_id->name, old_id, old_id->us, new_id ? new_id->name : "", new_id, new_id ? new_id->us : 0);
@@ -1270,20 +1308,6 @@ void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const
Object *old_ob = (Object *)old_id;
Object *new_ob = (Object *)new_id;
- if (new_ob == NULL) {
- Scene *sce;
- Base *base;
-
- for (sce = bmain->scene.first; sce; sce = sce->id.next) {
- base = BKE_scene_base_find(sce, old_ob);
-
- if (base) {
- BKE_scene_base_unlink(sce, base);
- MEM_freeN(base);
- }
- }
- }
-
if (old_ob->flag & OB_FROMGROUP) {
/* Note that for Scene's BaseObject->flag, either we:
* - unlinked old_ob (i.e. new_ob is NULL), in which case scenes' bases have been removed already.
@@ -1313,21 +1337,22 @@ void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const
DAG_relations_tag_update(bmain);
}
-void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage)
+void BKE_libblock_remap(
+ Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null)
{
BKE_main_lock(bmain);
- BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage);
+ BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage, do_flag_never_null);
BKE_main_unlock(bmain);
}
/** Unlink given \a id from given \a bmain (does not touch to indirect, i.e. library, usages of the ID). */
-void BKE_libblock_unlink(Main *bmain, void *idv)
+void BKE_libblock_unlink(Main *bmain, void *idv, const bool do_flag_never_null)
{
BKE_main_lock(bmain);
- BKE_libblock_remap_locked(bmain, idv, NULL, true);
+ BKE_libblock_remap_locked(bmain, idv, NULL, true, do_flag_never_null);
BKE_main_unlock(bmain);
}
@@ -1335,7 +1360,7 @@ void BKE_libblock_unlink(Main *bmain, void *idv)
/** Similar to libblock_remap, but only affects IDs used by given \a idv ID.
*
* \param old_id Unlike BKE_libblock_remap, can be NULL, in which case all ID usages by given \a idv will be cleared.
- * \param us_min_never_null If true and new_id is NULL, 'NEVER_NULL' ID usages keep their old id, but this one still
+ * \param us_min_never_null If \a true and new_id is NULL, 'NEVER_NULL' ID usages keep their old id, but this one still
* gets its user count decremented (needed when given \a idv is going to be deleted right after being unlinked).
*/
/* Should be able to replace all _relink() funcs (constraints, rigidbody, etc.) ? */
@@ -1346,7 +1371,8 @@ void BKE_libblock_unlink(Main *bmain, void *idv)
* BKE_id_remap maybe?
* ... sigh
*/
-void BKE_libblock_relink_ex(void *idv, void *old_idv, void *new_idv, const bool us_min_never_null)
+void BKE_libblock_relink_ex(
+ void *idv, void *old_idv, void *new_idv, const bool us_min_never_null)
{
ID *id = idv;
ID *old_id = old_idv;
@@ -1401,36 +1427,12 @@ void BKE_libblock_free_data(Main *bmain, ID *id)
BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
}
-typedef struct IDRecursiveDelete {
- ID *id_used;
- ID *id_user;
- bool changed;
-} IDRecursiveDelete;
-
-static bool foreach_libblock_recursive_delete_callback(void *user_data, ID **id_p, int cb_flag)
-{
- IDRecursiveDelete *id_recursive_delete = user_data;
- ID *id_used = id_recursive_delete->id_used;
- ID *id_user = id_recursive_delete->id_user;
-
- if ((*id_p == id_used) && (cb_flag & IDWALK_NEVER_NULL)) {
- id_user->flag |= LIB_DOIT;
- id_recursive_delete->changed = true;
- return false; /* No need
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list