[Bf-blender-cvs] [99a3e09] asset-experiments: Refactor code in multi-append/link operator.

Bastien Montagne noreply at git.blender.org
Thu May 28 14:43:13 CEST 2015


Commit: 99a3e0908820db954e4f33d6cffa49c54f9682cf
Author: Bastien Montagne
Date:   Thu May 28 14:42:12 2015 +0200
Branches: asset-experiments
https://developer.blender.org/rB99a3e0908820db954e4f33d6cffa49c54f9682cf

Refactor code in multi-append/link operator.

Avoid writing a big chunck of code doing nearly the same thing twice...

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

M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b55cba9..a37ea98 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2591,88 +2591,34 @@ static short wm_link_append_flag(wmOperator *op)
 	return flag;
 }
 
-static int wm_link_append_exec(bContext *C, wmOperator *op)
+/* Helper.
+ *     if `name` is non-NULL, we assume a single-item link/append.
+ *     else if `*todo_libraries` is NULL we assume first-run.
+ */
+static void wm_link_append_do_libgroup(
+        bContext *C, wmOperator *op, const char *root, const char *libname, char *group, char *name,
+        const short flag, GSet **todo_libraries)
 {
 	Main *bmain = CTX_data_main(C);
-	Scene *scene = CTX_data_scene(C);
-	Main *mainl = NULL;
+	Main *mainl;
 	BlendHandle *bh;
 	Library *lib;
-	PropertyRNA *prop;
-	char path[FILE_MAX_LIBEXTRA], dir[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX], *group, *name;
-	int idcode, totfiles = 0;
-	short flag;
-
-	GSet *todo_libraries = NULL;
-
-	RNA_string_get(op->ptr, "filename", relname);
-	RNA_string_get(op->ptr, "directory", dir);
 
-	BLI_join_dirfile(path, sizeof(path), dir, relname);
-
-	/* test if we have a valid data */
-	if (!BLO_library_path_explode(path, libname, &group, &name)) {
-		BKE_report(op->reports, RPT_ERROR, "Not a library");
-		return OPERATOR_CANCELLED;
-	}
-	else if (!group) {
-		BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
-		return OPERATOR_CANCELLED;
-	}
-	else if (BLI_path_cmp(bmain->name, libname) == 0) {
-		BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
-		return OPERATOR_CANCELLED;
-	}
+	char path[FILE_MAX_LIBEXTRA], relname[FILE_MAX];
+	int idcode;
+	const bool is_first_run = (*todo_libraries == NULL);
 
-	/* check if something is indicated for append/link */
-	prop = RNA_struct_find_property(op->ptr, "files");
-	if (prop) {
-		totfiles = RNA_property_collection_length(op->ptr, prop);
-		if (totfiles == 0) {
-			if (!name) {
-				BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
-				return OPERATOR_CANCELLED;
-			}
-		}
-	}
-	else if (!name) {
-		BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
-		return OPERATOR_CANCELLED;
-	}
+	BLI_assert(group);
+	idcode = BKE_idcode_from_name(group);
 
 	bh = BLO_blendhandle_from_file(libname, op->reports);
 
 	if (bh == NULL) {
 		/* unlikely since we just browsed it, but possible
 		 * error reports will have been made by BLO_blendhandle_from_file() */
-		return OPERATOR_CANCELLED;
-	}
-
-
-	/* from here down, no error returns */
-
-	/* now we have or selected, or an indicated file */
-	if (RNA_boolean_get(op->ptr, "autoselect"))
-		BKE_scene_base_deselect_all(scene);
-
-	
-	flag = wm_link_append_flag(op);
-
-	/* sanity checks for flag */
-	if (scene->id.lib && (flag & FILE_GROUP_INSTANCE)) {
-		/* TODO, user never gets this message */
-		BKE_reportf(op->reports, RPT_WARNING, "Scene '%s' is linked, group instance disabled", scene->id.name + 2);
-		flag &= ~FILE_GROUP_INSTANCE;
+		return;
 	}
 
-	idcode = BKE_idcode_from_name(group);
-
-	/* tag everything, all untagged data can be made local
-	 * its also generally useful to know what is new
-	 *
-	 * take extra care BKE_main_id_flag_all(LIB_LINK_TAG, false) is called after! */
-	BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, 1);
-
 	/* here appending/linking starts */
 	mainl = BLO_library_append_begin(bmain, &bh, libname);
 	lib = mainl->curlib;
@@ -2685,11 +2631,13 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 		            mainl->versionfile, mainl->subversionfile);
 	}
 
-	if (totfiles == 0) {
+	if (name) {
 		BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
 	}
 	else {
-		todo_libraries = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
+		if (is_first_run) {
+			*todo_libraries = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
+		}
 
 		RNA_BEGIN (op->ptr, itemptr, "files")
 		{
@@ -2698,7 +2646,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 
 			RNA_string_get(&itemptr, "name", relname);
 
-			BLI_join_dirfile(path, sizeof(path), dir, relname);
+			BLI_join_dirfile(path, sizeof(path), root, relname);
 
 			if (BLO_library_path_explode(path, curr_libname, &group, &name)) {
 				if (!group || !name) {
@@ -2710,10 +2658,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 				if ((idcode == curr_idcode) && (BLI_path_cmp(curr_libname, libname) == 0)) {
 					BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
 				}
-				else {
+				else if (is_first_run) {
 					BLI_join_dirfile(path, sizeof(path), curr_libname, group);
-					if (!BLI_gset_haskey(todo_libraries, path)) {
-						BLI_gset_insert(todo_libraries, BLI_strdup(path));
+					if (!BLI_gset_haskey(*todo_libraries, path)) {
+						BLI_gset_insert(*todo_libraries, BLI_strdup(path));
 					}
 				}
 			}
@@ -2721,7 +2669,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 		RNA_END;
 	}
 	BLO_library_append_end(C, mainl, &bh, idcode, flag);
-	
+
+	BLO_blendhandle_close(bh);
+
 	/* mark all library linked objects to be updated */
 	BKE_main_lib_objects_recalc_all(bmain);
 	IMB_colormanagement_check_file_config(bmain);
@@ -2731,68 +2681,90 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 		BLI_assert(BLI_findindex(&bmain->library, lib) != -1);
 		BKE_library_make_local(bmain, lib, true);
 	}
+}
 
-	BLO_blendhandle_close(bh);
+static int wm_link_append_exec(bContext *C, wmOperator *op)
+{
+	Main *bmain = CTX_data_main(C);
+	Scene *scene = CTX_data_scene(C);
+	PropertyRNA *prop;
+	char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX], *group, *name;
+	int totfiles = 0;
+	short flag;
 
-	if (todo_libraries) {
-		GSetIterator libs_it;
+	GSet *todo_libraries = NULL;
 
-		GSET_ITER(libs_it, todo_libraries) {
-			char *libpath = (char *)BLI_gsetIterator_getKey(&libs_it);
+	RNA_string_get(op->ptr, "filename", relname);
+	RNA_string_get(op->ptr, "directory", root);
 
-			BLO_library_path_explode(libpath, libname, &group, NULL);
-			BLI_assert(group);
-			idcode = BKE_idcode_from_name(group);
+	BLI_join_dirfile(path, sizeof(path), root, relname);
 
-			bh = BLO_blendhandle_from_file(libname, op->reports);
+	/* test if we have a valid data */
+	if (!BLO_library_path_explode(path, libname, &group, &name)) {
+		BKE_report(op->reports, RPT_ERROR, "Not a library");
+		return OPERATOR_CANCELLED;
+	}
+	else if (!group) {
+		BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+		return OPERATOR_CANCELLED;
+	}
+	else if (BLI_path_cmp(bmain->name, libname) == 0) {
+		BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
+		return OPERATOR_CANCELLED;
+	}
 
-			if (bh == NULL) {
-				/* unlikely since we just browsed it, but possible
-				 * error reports will have been made by BLO_blendhandle_from_file() */
-				continue;
+	/* check if something is indicated for append/link */
+	prop = RNA_struct_find_property(op->ptr, "files");
+	if (prop) {
+		totfiles = RNA_property_collection_length(op->ptr, prop);
+		if (totfiles == 0) {
+			if (!name) {
+				BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+				return OPERATOR_CANCELLED;
 			}
+		}
+	}
+	else if (!name) {
+		BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+		return OPERATOR_CANCELLED;
+	}
 
-			/* here appending/linking starts */
-			mainl = BLO_library_append_begin(bmain, &bh, libname);
-			lib = mainl->curlib;
-			BLI_assert(lib);
-
-			RNA_BEGIN (op->ptr, itemptr, "files")
-			{
-				char curr_libname[FILE_MAX];
-				int curr_idcode;
+	flag = wm_link_append_flag(op);
 
-				RNA_string_get(&itemptr, "name", relname);
+	/* sanity checks for flag */
+	if (scene->id.lib && (flag & FILE_GROUP_INSTANCE)) {
+		/* TODO, user never gets this message */
+		BKE_reportf(op->reports, RPT_WARNING, "Scene '%s' is linked, group instance disabled", scene->id.name + 2);
+		flag &= ~FILE_GROUP_INSTANCE;
+	}
 
-				BLI_join_dirfile(path, sizeof(path), dir, relname);
+	/* from here down, no error returns */
 
-				if (BLO_library_path_explode(path, curr_libname, &group, &name)) {
-					if (!group || !name) {
-						continue;
-					}
+	/* now we have or selected, or an indicated file */
+	if (RNA_boolean_get(op->ptr, "autoselect"))
+		BKE_scene_base_deselect_all(scene);
+	
+	/* tag everything, all untagged data can be made local
+	 * its also generally useful to know what is new
+	 *
+	 * take extra care BKE_main_id_flag_all(LIB_LINK_TAG, false) is called after! */
+	BKE_main_id_flag_all(bmain, LIB_PRE_EXISTING, 1);
 
-					curr_idcode = BKE_idcode_from_name(group);
+	if (totfiles != 0) {
+		name = NULL;
+	}
 
-					if ((idcode == curr_idcode) && (BLI_path_cmp(curr_libname, libname) == 0)) {
-						BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
-					}
-				}
-			}
-			RNA_END;
+	wm_link_append_do_libgroup(C, op, root, libname, group, name, flag, &todo_libraries);
 
-			BLO_library_append_end(C, mainl, &bh, idcode, flag);
+	if (todo_libraries) {
+		GSetIterator libs_it;
 
-			/* mark all library linked objects to be updated */
-			BKE_main_lib_objects_recalc_all(bmain);
-			IMB_colormanagement_check_file_config(bmain);
+		GSET_ITER(libs_it, todo_libraries) {
+			char *libpath = (char *)BLI_gsetIterator_getKey(&libs_it);
 
-			/* append, rather than linking */
-			if ((flag & FILE_LINK) == 0) {
-				BLI_assert(BLI_findindex(&bmain->library, lib) != -1);
-				BKE_library_make_local(bmain, lib, true);
-			}
+			BLO_library_path_explode(libpath, libname, &group, NULL);
 
-			BLO_blendhandle_close(bh);
+			wm_link_append_do_libgroup(C, op, root, libname, group, NULL, flag, &todo_libraries);
 		}
 
 		BLI_gset_free(todo_libraries, MEM_freeN);
@@ -2809,7 +2781,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
 	GPU_materials_free();
 
 	/* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */
-	BLI_strncpy(G.lib, dir, FILE_MAX);
+	BLI_strncpy(G.lib, root, FILE_MAX);
 
 	WM_event_add_notifier(C, NC_WINDOW, NULL);




More information about the Bf-blender-cvs mailing list