From 145ff58277a5145026be9887666a2acd50559e80 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 29 Aug 2017 19:50:58 -0300 Subject: [PATCH] Fix constant reimport on broken files, closes #9930 --- core/io/resource_import.cpp | 24 ++++++++++++++++-- core/io/resource_import.h | 3 ++- core/io/resource_loader.cpp | 25 +++++++++++++++++++ core/io/resource_loader.h | 2 ++ editor/editor_file_system.cpp | 46 +++++++++++++++++++++++------------ editor/editor_file_system.h | 2 ++ 6 files changed, 84 insertions(+), 18 deletions(-) diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index 5a4f29fe67b..69ff791a3ad 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -32,13 +32,17 @@ #include "os/os.h" #include "variant_parser.h" -Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type) const { +Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { Error err; FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); - if (!f) + if (!f) { + if (r_valid) { + *r_valid = false; + } return err; + } VariantParser::StreamFile stream; stream.f = f; @@ -47,6 +51,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy Variant value; VariantParser::Tag next_tag; + if (r_valid) { + *r_valid = true; + } + int lines = 0; String error_text; bool path_found = false; //first match must have priority @@ -79,6 +87,10 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy path_found = true; //first match must have priority } else if (assign == "type") { r_path_and_type.type = value; + } else if (assign == "valid") { + if (r_valid) { + *r_valid = value; + } } } else if (next_tag.name != "remap") { @@ -245,6 +257,14 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat memdelete(f); } +bool ResourceFormatImporter::is_import_valid(const String &p_path) const { + + bool valid = true; + PathAndType pat; + _get_path_and_type(p_path, pat, &valid); + return valid; +} + String ResourceFormatImporter::get_resource_type(const String &p_path) const { PathAndType pat; diff --git a/core/io/resource_import.h b/core/io/resource_import.h index bf0bf3987a0..b10255fbab6 100644 --- a/core/io/resource_import.h +++ b/core/io/resource_import.h @@ -40,7 +40,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { String type; }; - Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type) const; + Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; static ResourceFormatImporter *singleton; @@ -54,6 +54,7 @@ public: virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; + virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); virtual bool can_be_imported(const String &p_path) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index f0e804e2faa..30ae9f5681e 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -296,6 +296,31 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l } } +bool ResourceLoader::is_import_valid(const String &p_path) { + + String path = _path_remap(p_path); + + String local_path; + if (path.is_rel_path()) + local_path = "res://" + path; + else + local_path = ProjectSettings::get_singleton()->localize_path(path); + + for (int i = 0; i < loader_count; i++) { + + if (!loader[i]->recognize_path(local_path)) + continue; + /* + if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) + continue; + */ + + return loader[i]->is_import_valid(p_path); + } + + return false; //not found +} + void ResourceLoader::get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types) { String path = _path_remap(p_path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 9e059c29779..91f0c939bf1 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -66,6 +66,7 @@ public: virtual String get_resource_type(const String &p_path) const = 0; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const Map &p_map) { return OK; } + virtual bool is_import_valid(const String &p_path) const { return true; } virtual ~ResourceFormatLoader() {} }; @@ -104,6 +105,7 @@ public: static String get_resource_type(const String &p_path); static void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const Map &p_map); + static bool is_import_valid(const String &p_path); static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 9d110c71362..48825d52188 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -181,7 +181,7 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2"); + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); if (f) { @@ -201,7 +201,7 @@ void EditorFileSystem::_scan_filesystem() { } else { Vector split = l.split("::"); - ERR_CONTINUE(split.size() != 5); + ERR_CONTINUE(split.size() != 6); String name = split[0]; String file; @@ -212,8 +212,9 @@ void EditorFileSystem::_scan_filesystem() { fc.type = split[1]; fc.modification_time = split[2].to_int64(); fc.import_modification_time = split[3].to_int64(); + fc.import_valid = split[4].to_int64() != 0; - String deps = split[4].strip_edges(); + String deps = split[5].strip_edges(); if (deps.length()) { Vector dp = deps.split("<>"); for (int i = 0; i < dp.size(); i++) { @@ -230,7 +231,7 @@ void EditorFileSystem::_scan_filesystem() { memdelete(f); } - String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2"); + String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3"); print_line("try to see fs update2"); if (FileAccess::exists(update_cache)) { @@ -282,7 +283,7 @@ void EditorFileSystem::_scan_filesystem() { } void EditorFileSystem::_save_filesystem_cache() { - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2"); + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); _save_filesystem_cache(filesystem, f); @@ -622,6 +623,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->deps = fc->deps; fi->modified_time = fc->modification_time; fi->import_modified_time = fc->import_modification_time; + fi->import_valid = fc->import_valid; if (fc->type == String()) { fi->type = ResourceLoader::get_resource_type(path); //there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?) @@ -648,6 +650,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess print_line("import extension tried resource type for " + path + " and its " + fi->type); fi->modified_time = 0; fi->import_modified_time = 0; + fi->import_valid = ResourceLoader::is_import_valid(path); ItemAction ia; ia.action = ItemAction::ACTION_FILE_REIMPORT; @@ -663,6 +666,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess fi->modified_time = fc->modification_time; fi->deps = fc->deps; fi->import_modified_time = 0; + fi->import_valid = true; } else { //new or modified time fi->type = ResourceLoader::get_resource_type(path); @@ -670,6 +674,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess print_line("regular import tried resource type for " + path + " and its " + fi->type); fi->modified_time = mt; fi->import_modified_time = 0; + fi->import_valid = true; } } @@ -766,6 +771,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const fi->modified_time = FileAccess::get_modified_time(path); fi->import_modified_time = 0; fi->type = ResourceLoader::get_resource_type(path); + fi->import_valid = ResourceLoader::is_import_valid(path); { ItemAction ia; @@ -1036,7 +1042,7 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir, for (int i = 0; i < p_dir->files.size(); i++) { - String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time); + String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid); s += "::"; for (int j = 0; j < p_dir->files[i]->deps.size(); j++) { @@ -1217,7 +1223,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p void EditorFileSystem::_save_late_updated_files() { //files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2"); + String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3"); FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE); for (Set::Element *E = late_update_files.front(); E; E = E->next()) { f->store_line(E->get()); @@ -1281,6 +1287,7 @@ void EditorFileSystem::update_file(const String &p_file) { EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); fi->file = p_file.get_file(); fi->import_modified_time = 0; + fi->import_valid = ResourceLoader::is_import_valid(p_file); if (idx == fs->files.size()) { fs->files.push_back(fi); @@ -1301,6 +1308,7 @@ void EditorFileSystem::update_file(const String &p_file) { fs->files[cpos]->type = type; fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->deps = _get_dependencies(p_file); + fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); //if (FileAccess::exists(p_file+".import")) { // fs->files[cpos]->import_modified_time=FileAccess::get_modified_time(p_file+".import"); //} @@ -1404,19 +1412,26 @@ void EditorFileSystem::_reimport_file(const String &p_file) { f->store_line("type=\"" + importer->get_resource_type() + "\""); } - if (importer->get_save_extension() == "") { - //no path - } else if (import_variants.size()) { - //import with variants - for (List::Element *E = import_variants.front(); E; E = E->next()) { + if (err == OK) { - String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension(); + if (importer->get_save_extension() == "") { + //no path + } else if (import_variants.size()) { + //import with variants + for (List::Element *E = import_variants.front(); E; E = E->next()) { - f->store_line("path." + E->get() + "=\"" + path + "\""); + String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension(); + + f->store_line("path." + E->get() + "=\"" + path + "\""); + } + } else { + + f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\""); } + } else { - f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\""); + f->store_line("valid=false"); } f->store_line(""); @@ -1455,6 +1470,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import"); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->type = importer->get_resource_type(); + fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it //to reload properly diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 4d9a96d2331..efbbec0e081 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -54,6 +54,7 @@ class EditorFileSystemDirectory : public Object { StringName type; uint64_t modified_time; uint64_t import_modified_time; + bool import_valid; Vector deps; bool verified; //used for checking changes }; @@ -153,6 +154,7 @@ class EditorFileSystem : public Node { uint64_t modification_time; uint64_t import_modification_time; Vector deps; + bool import_valid; }; HashMap file_cache;