[Bf-blender-cvs] [705a247] id-remap: Better handling of usercount during ID deletion, also add this to ID RNA API.

Bastien Montagne noreply at git.blender.org
Thu Dec 3 16:36:55 CET 2015


Commit: 705a247e2eb37f454da4ebfed5ec504518c524f1
Author: Bastien Montagne
Date:   Thu Dec 3 16:34:11 2015 +0100
Branches: id-remap
https://developer.blender.org/rB705a247e2eb37f454da4ebfed5ec504518c524f1

Better handling of usercount during ID deletion, also add this to ID RNA API.

Seems to work for simple cases, but deletion of complex libs from complex files
(Gooseberry ones) still generates lots of assert failures, and crashes in some cases.

===================================================================

M	source/blender/blenkernel/BKE_library.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/library_query.c
M	source/blender/editors/screen/screen_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/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index fb9f443..9aec4b5 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -60,9 +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_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
+        struct Main *bmain, void *old_idv, void *new_idv,
+        const bool skip_indirect_usage, const bool us_min_never_null, 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, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
+        struct Main *bmain, void *old_idv, void *new_idv,
+        const bool skip_indirect_usage, const bool us_min_never_null, const bool do_flag_never_null) ATTR_NONNULL(1, 2);
 
 void BKE_libblock_unlink(struct Main *bmain, void *idv, const bool do_flag_never_null) ATTR_NONNULL();
 
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index a975a06..ada6ccb 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -203,7 +203,8 @@ void id_us_min(ID *id)
 		}
 
 		if (id->us <= limit) {
-			printf("ID user decrement error: %s (from '%s')\n", id->name, id->lib ? id->lib->filepath : "[Main]");
+			printf("ID user decrement error: %s (from '%s'): %d <= %d\n",
+			       id->name, id->lib ? id->lib->filepath : "[Main]", id->us, limit);
 			BLI_assert(0);
 			id->us = limit;
 		}
@@ -1226,13 +1227,15 @@ static void libblock_remap_data(
  *                           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)
+        Main *bmain, void *old_idv, void *new_idv,
+        const bool skip_indirect_usage, const bool us_min_never_null, 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) |
-	                   (do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE : 0));
+	                   (do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE : 0) |
+	                   (us_min_never_null ? 0 : ID_REMAP_SKIP_NEVER_NULL_USAGE));
 	int skipped_direct, skipped_refcounted;
 
 	BLI_assert(old_id != NULL);
@@ -1327,6 +1330,10 @@ void BKE_libblock_remap_locked(
 			}
 		}
 	}
+	else if (GS(old_id->name) == ID_LI) {
+		/* Libraries have one user, though they are not technically used by anyone... */
+		id_us_min(old_id);
+	}
 
 //	if (GS(old_id->name) == ID_AC) {
 //		printf("%s: END   %s (%p, %d) replaced by %s (%p, %d)\n",
@@ -1338,11 +1345,12 @@ void BKE_libblock_remap_locked(
 }
 
 void BKE_libblock_remap(
-        Main *bmain, void *old_idv, void *new_idv, const bool skip_indirect_usage, const bool do_flag_never_null)
+        Main *bmain, void *old_idv, void *new_idv,
+        const bool skip_indirect_usage, const bool us_min_never_null, const bool do_flag_never_null)
 {
 	BKE_main_lock(bmain);
 
-	BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage, do_flag_never_null);
+	BKE_libblock_remap_locked(bmain, old_idv, new_idv, skip_indirect_usage, us_min_never_null, do_flag_never_null);
 
 	BKE_main_unlock(bmain);
 }
@@ -1352,7 +1360,7 @@ 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, do_flag_never_null);
+	BKE_libblock_remap_locked(bmain, idv, NULL, true, false, do_flag_never_null);
 
 	BKE_main_unlock(bmain);
 }
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 613d6b4..9fdac85 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -238,6 +238,12 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
 	FOREACH_CALLBACK_INVOKE(id, check_id_super, flag, callback, user_data, cb_flag)
 
 	switch (GS(id->name)) {
+		case ID_LI:
+		{
+			Library *lib = (Library *) id;
+			CALLBACK_INVOKE(lib->parent, IDWALK_NOP);
+			break;
+		}
 		case ID_SCE:
 		{
 			Scene *scene = (Scene *) id;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 7a4d3e3..d491dfe 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1747,7 +1747,7 @@ bool ED_screen_delete_scene(bContext *C, Scene *scene)
 
 	ED_screen_set_scene(C, CTX_wm_screen(C), newscene);
 
-	BKE_libblock_remap(bmain, scene, newscene, true, false);
+	BKE_libblock_remap(bmain, scene, newscene, true, false, false);
 
 	BKE_libblock_free(bmain, scene);
 
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 1c7a860..d05b5e1 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -1380,7 +1380,7 @@ static void remap_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUS
 	ID *new_id = user_data;
 
 	if (tselem->id && (tselem->id != new_id) && (GS(tselem->id->name) == GS(new_id->name))) {
-		BKE_libblock_remap(CTX_data_main(C), tselem->id, new_id, true, false);
+		BKE_libblock_remap(CTX_data_main(C), tselem->id, new_id, true, false, false);
 	}
 }
 
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 81c3f13..8ec673e 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -334,10 +334,15 @@ static void rna_ID_user_clear(ID *id)
 	id->us = 0; /* don't save */
 }
 
+static void rna_ID_delete(ID *id, Main *bmain)
+{
+	BKE_libblock_delete(bmain, id);
+}
+
 static void rna_ID_user_remap(ID *id, Main *bmain, ID *new_id)
 {
 	if (GS(id->name) == GS(new_id->name)) {
-		BKE_libblock_remap(bmain, id, new_id, true, false);  /* Now, do not allow remapping data in linked data from here... */
+		BKE_libblock_remap(bmain, id, new_id, true, false, false);  /* Now, do not allow remapping data in linked data from here... */
 	}
 }
 
@@ -1003,6 +1008,10 @@ static void rna_def_ID(BlenderRNA *brna)
 	parm = RNA_def_pointer(func, "id", "ID", "", "New copy of the ID");
 	RNA_def_function_return(func, parm);
 
+	func = RNA_def_function(srna, "destroy", "rna_ID_delete");
+	RNA_def_function_flag(func, FUNC_USE_MAIN);
+	RNA_def_function_ui_description(func, "Delete this ID from Blender (WARNING: no undo, do not use it after calling this!)");
+
 	func = RNA_def_function(srna, "user_clear", "rna_ID_user_clear");
 	RNA_def_function_ui_description(func, "Clear the user count of a data-block so its not saved, "
 	                                "on reload the data will be removed");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 94d9678..afb2875 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -160,7 +160,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
 
 		}
 
-		BKE_libblock_remap(bmain, scene, scene_new, true, false);
+		BKE_libblock_remap(bmain, scene, scene_new, true, false, false);
 		BKE_libblock_free(bmain, scene);
 		RNA_POINTER_INVALIDATE(scene_ptr);
 	}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index ea16cb0..87d6351 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3125,7 +3125,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, const bool reloa
 				if (new_id) {
 //					printf("before remap, old_id users: %d (%p), new_id users: %d (%p)\n", old_id->us, old_id, new_id->us, new_id);
 					/* Note that here, we also want to replace indirect usages. */
-					BKE_libblock_remap_locked(bmain, old_id, new_id, false, false);
+					BKE_libblock_remap_locked(bmain, old_id, new_id, false, false, false);
 
 //					printf("after remap, old_id users: %d, new_id users: %d\n", old_id->us, new_id->us);
 
@@ -3254,7 +3254,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, const bool reloa
 				BLI_assert(old_id);
 				if (new_id) {
 //					printf("before remap, old_id users: %d, new_id users: %d\n", old_id->us, new_id->us);
-					BKE_libblock_remap_locked(bmain, old_id, new_id, true, false);
+					BKE_libblock_remap_locked(bmain, old_id, new_id, true, false, false);
 
 					if (old_id->flag & LIB_FAKEUSER) {
 						id_fake_user_clear(old_id);




More information about the Bf-blender-cvs mailing list