Browse Source

Changed reimport logic to also check md5 before reimporting, fixes #13135
Has the nice side effect that you can share your .import folder or rename
your project and godot wont reimport stuff.

Juan Linietsky 8 years ago
parent
commit
bb83c7d6b7
2 changed files with 104 additions and 76 deletions
  1. 102 74
      editor/editor_file_system.cpp
  2. 2 2
      editor/editor_file_system.h

+ 102 - 74
editor/editor_file_system.cpp

@@ -296,6 +296,89 @@ void EditorFileSystem::_thread_func(void *_userdata) {
 	sd->_scan_filesystem();
 }
 
+bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_imported_files) {
+
+	if (!reimport_on_missing_imported_files && p_only_imported_files)
+		return false;
+
+	Error err;
+	FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
+
+	if (!f) { //no import file, do reimport
+		return true;
+	}
+
+	VariantParser::StreamFile stream;
+	stream.f = f;
+
+	String assign;
+	Variant value;
+	VariantParser::Tag next_tag;
+
+	int lines = 0;
+	String error_text;
+
+	List<String> to_check;
+
+	String source_md5;
+
+	while (true) {
+
+		assign = Variant();
+		next_tag.fields.clear();
+		next_tag.name = String();
+
+		err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
+		if (err == ERR_FILE_EOF) {
+			memdelete(f);
+			break;
+		} else if (err != OK) {
+			ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text);
+			memdelete(f);
+			return false; //parse error, try reimport manually (Avoid reimport loop on broken file)
+		}
+
+		if (assign != String()) {
+			if (assign.begins_with("path")) {
+				to_check.push_back(value);
+			} else if (assign == "files") {
+				Array fa = value;
+				for (int i = 0; i < fa.size(); i++) {
+					to_check.push_back(fa[i]);
+				}
+			} else if (!p_only_imported_files && assign == "source_md5") {
+				source_md5 = value;
+			}
+
+		} else if (next_tag.name != "remap" && next_tag.name != "deps") {
+			break;
+		}
+	}
+
+	memdelete(f);
+
+	//imported files are gone, reimport
+	for (List<String>::Element *E = to_check.front(); E; E = E->next()) {
+		if (!FileAccess::exists(E->get())) {
+			return true;
+		}
+	}
+
+	//check source md5 matching
+	if (!p_only_imported_files) {
+		if (source_md5 == String()) {
+			return true; //lacks md5, so just reimport
+		}
+
+		String md5 = FileAccess::get_md5(p_path);
+		if (md5 != source_md5) {
+			return true;
+		}
+	}
+
+	return false; //nothing changed
+}
+
 bool EditorFileSystem::_update_scan_actions() {
 
 	sources_changed.clear();
@@ -365,12 +448,20 @@ bool EditorFileSystem::_update_scan_actions() {
 				fs_changed = true;
 
 			} break;
-			case ItemAction::ACTION_FILE_REIMPORT: {
+			case ItemAction::ACTION_FILE_TEST_REIMPORT: {
 
 				int idx = ia.dir->find_file_index(ia.file);
 				ERR_CONTINUE(idx == -1);
 				String full_path = ia.dir->get_file_path(idx);
-				reimports.push_back(full_path);
+				if (_test_for_reimport(full_path, false)) {
+					//must reimport
+					reimports.push_back(full_path);
+				} else {
+					//must not reimport, all was good
+					//update modified times, to avoid reimport
+					ia.dir->files[idx]->modified_time = FileAccess::get_modified_time(full_path);
+					ia.dir->files[idx]->import_modified_time = FileAccess::get_modified_time(full_path + ".import");
+				}
 
 				fs_changed = true;
 			} break;
@@ -440,72 +531,6 @@ EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_cur
 	return sp;
 }
 
-bool EditorFileSystem::_check_missing_imported_files(const String &p_path) {
-
-	if (!reimport_on_missing_imported_files)
-		return true;
-
-	Error err;
-	FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
-
-	if (!f) {
-		print_line("could not open import for " + p_path);
-		return false;
-	}
-
-	VariantParser::StreamFile stream;
-	stream.f = f;
-
-	String assign;
-	Variant value;
-	VariantParser::Tag next_tag;
-
-	int lines = 0;
-	String error_text;
-
-	List<String> to_check;
-
-	while (true) {
-
-		assign = Variant();
-		next_tag.fields.clear();
-		next_tag.name = String();
-
-		err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
-		if (err == ERR_FILE_EOF) {
-			memdelete(f);
-			return OK;
-		} else if (err != OK) {
-			ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text);
-			memdelete(f);
-			return false;
-		}
-
-		if (assign != String()) {
-			if (assign.begins_with("path")) {
-				to_check.push_back(value);
-			} else if (assign == "files") {
-				Array fa = value;
-				for (int i = 0; i < fa.size(); i++) {
-					to_check.push_back(fa[i]);
-				}
-			}
-
-		} else if (next_tag.name != "remap" && next_tag.name != "deps") {
-			break;
-		}
-	}
-
-	memdelete(f);
-
-	for (List<String>::Element *E = to_check.front(); E; E = E->next()) {
-		if (!FileAccess::exists(E->get())) {
-			return false;
-		}
-	}
-	return true;
-}
-
 void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess *da, const ScanProgress &p_progress) {
 
 	List<String> dirs;
@@ -611,7 +636,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
 				import_mt = FileAccess::get_modified_time(path + ".import");
 			}
 
-			if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && _check_missing_imported_files(path)) {
+			if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && !_test_for_reimport(path, true)) {
 
 				fi->type = fc->type;
 				fi->deps = fc->deps;
@@ -632,7 +657,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
 				fi->import_valid = ResourceLoader::is_import_valid(path);
 
 				ItemAction ia;
-				ia.action = ItemAction::ACTION_FILE_REIMPORT;
+				ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT;
 				ia.dir = p_dir;
 				ia.file = E->get();
 				scan_actions.push_back(ia);
@@ -761,7 +786,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
 					if (import_extensions.has(ext)) {
 						//if it can be imported, and it was added, it needs to be reimported
 						ItemAction ia;
-						ia.action = ItemAction::ACTION_FILE_REIMPORT;
+						ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT;
 						ia.dir = p_dir;
 						ia.file = f;
 						scan_actions.push_back(ia);
@@ -807,7 +832,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
 				uint64_t import_mt = FileAccess::get_modified_time(path + ".import");
 				if (import_mt != p_dir->files[i]->import_modified_time) {
 					reimport = true;
-				} else if (!_check_missing_imported_files(path)) {
+				} else if (_test_for_reimport(path, true)) {
 					reimport = true;
 				}
 			}
@@ -815,7 +840,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
 			if (reimport) {
 
 				ItemAction ia;
-				ia.action = ItemAction::ACTION_FILE_REIMPORT;
+				ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT;
 				ia.dir = p_dir;
 				ia.file = p_dir->files[i]->file;
 				scan_actions.push_back(ia);
@@ -1385,8 +1410,9 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
 
 	f->store_line("");
 
+	f->store_line("[deps]");
+
 	if (gen_files.size()) {
-		f->store_line("[gen]");
 		Array genf;
 		for (List<String>::Element *E = gen_files.front(); E; E = E->next()) {
 			genf.push_back(E->get());
@@ -1398,6 +1424,8 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
 		f->store_line("");
 	}
 
+	f->store_line("source_md5=\"" + FileAccess::get_md5(p_file) + "\"");
+
 	f->store_line("[params]");
 	f->store_line("");
 

+ 2 - 2
editor/editor_file_system.h

@@ -109,7 +109,7 @@ class EditorFileSystem : public Node {
 			ACTION_DIR_REMOVE,
 			ACTION_FILE_ADD,
 			ACTION_FILE_REMOVE,
-			ACTION_FILE_REIMPORT
+			ACTION_FILE_TEST_REIMPORT
 		};
 
 		Action action;
@@ -200,7 +200,7 @@ class EditorFileSystem : public Node {
 
 	void _reimport_file(const String &p_file);
 
-	bool _check_missing_imported_files(const String &p_path);
+	bool _test_for_reimport(const String &p_path, bool p_only_imported_files);
 
 	bool reimport_on_missing_imported_files;