From 91c3066c89e647e7edba3f88dd08cdb7e464f9ab Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 31 Jan 2023 15:59:52 +0100 Subject: [PATCH] Support reimport appending * Add API: `EditorFileSystem::reimport_append(path)`, thread safe, what can be used from importers when they generate new files within the import process. * Added a `remap.gen_param` custom value to .import files, which can be used by importers to store data needed to generate this file again or not. This API is added to allow the GLTF2 importer to properly extract png files as textures. --- doc/classes/EditorImportPlugin.xml | 9 +++++++ editor/editor_file_system.cpp | 36 ++++++++++++++++++-------- editor/editor_file_system.h | 3 ++- editor/import/editor_import_plugin.cpp | 16 ++++++++++++ editor/import/editor_import_plugin.h | 3 +++ 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index ec9efcc9c46..a71d283e495 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -221,5 +221,14 @@ This method must be overridden to do the actual importing work. See this class' description for an example of overriding this method. + + + + + + + This function can only be called during the [method _import] callback and it allows manually importing resources from it. This is useful when the imported file generates external resources that require importing (as example, images). Custom parameters for the ".import" file can be passed via the [param custom_options]. Additionally, in cases where multiple importers can handle a file, the [param custom_importer] ca be specified to force a specific one. This function performs a resource import and returns immediately with a success or error code. + + diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 4d0ef3fe8d9..46f5f5017ec 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1900,11 +1900,11 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector return err; } -void EditorFileSystem::_reimport_file(const String &p_file, const HashMap *p_custom_options, const String &p_custom_importer) { +Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap *p_custom_options, const String &p_custom_importer) { EditorFileSystemDirectory *fs = nullptr; int cpos = -1; bool found = _find_file(p_file, &fs, cpos); - ERR_FAIL_COND_MSG(!found, "Can't find file '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(!found, ERR_FILE_NOT_FOUND, "Can't find file '" + p_file + "'."); //try to obtain existing params @@ -1919,6 +1919,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapget_value("remap", "uid"); uid = ResourceUID::get_singleton()->text_to_id(uidt); } + + if (cf->has_section_key("remap", "gen_params")) { + gen_params = cf->get_value("remap", "gen_params"); + } } } } @@ -1957,7 +1962,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapfiles[cpos]->type = ""; fs->files[cpos]->import_valid = false; EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); - return; + return OK; } Ref importer; bool load_default = false; @@ -1971,8 +1976,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapget_importer_by_extension(p_file.get_extension()); load_default = true; if (importer.is_null()) { - ERR_PRINT("BUG: File queued for import, but can't be imported, importer for type '" + importer_name + "' not found."); - ERR_FAIL(); + ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "BUG: File queued for import, but can't be imported, importer for type '" + importer_name + "' not found."); } } @@ -2005,16 +2009,14 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapimport(p_file, base_path, params, &import_variants, &gen_files, &meta); - if (err != OK) { - ERR_PRINT("Error importing '" + p_file + "'."); - } + ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_UNRECOGNIZED, "Error importing '" + p_file + "'."); //as import is complete, save the .import file Vector dest_paths; { Ref f = FileAccess::open(p_file + ".import", FileAccess::WRITE); - ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file from path '" + p_file + ".import'."); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_FILE_CANT_OPEN, "Cannot open file from path '" + p_file + ".import'."); //write manually, as order matters ([remap] has to go first for performance). f->store_line("[remap]"); @@ -2059,6 +2061,10 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapstore_line("metadata=" + meta.get_construct_string()); } + if (gen_params != Variant()) { + f->store_line("gen_params=" + gen_params.get_construct_string()); + } + f->store_line(""); f->store_line("[deps]\n"); @@ -2102,7 +2108,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap md5s = FileAccess::open(base_path + ".md5", FileAccess::WRITE); - ERR_FAIL_COND_MSG(md5s.is_null(), "Cannot open MD5 file '" + base_path + ".md5'."); + ERR_FAIL_COND_V_MSG(md5s.is_null(), ERR_FILE_CANT_OPEN, "Cannot open MD5 file '" + base_path + ".md5'."); md5s->store_line("source_md5=\"" + FileAccess::get_md5(p_file) + "\""); if (dest_paths.size()) { @@ -2136,6 +2142,8 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMapcheck_for_invalidation(p_file); + + return OK; } void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, HashMap> &group_files, HashSet &groups_to_reimport) { @@ -2166,10 +2174,11 @@ void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_im void EditorFileSystem::reimport_files(const Vector &p_files) { importing = true; - EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); Vector reloads; + EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); + Vector reimport_files; HashSet groups_to_reimport; @@ -2292,6 +2301,11 @@ void EditorFileSystem::reimport_files(const Vector &p_files) { emit_signal(SNAME("resources_reimported"), reloads); } +Error EditorFileSystem::reimport_append(const String &p_file, const HashMap &p_custom_options, const String &p_custom_importer) { + ERR_FAIL_COND_V_MSG(!importing, ERR_INVALID_PARAMETER, "Can only append files to import during a current reimport process."); + return _reimport_file(p_file, &p_custom_options, p_custom_importer); +} + Error EditorFileSystem::_resource_import(const String &p_path) { Vector files; files.push_back(p_path); diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 2490bd31b37..79101813aca 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -242,7 +242,7 @@ class EditorFileSystem : public Node { void _update_extensions(); - void _reimport_file(const String &p_file, const HashMap *p_custom_options = nullptr, const String &p_custom_importer = String()); + Error _reimport_file(const String &p_file, const HashMap *p_custom_options = nullptr, const String &p_custom_importer = String()); Error _reimport_group(const String &p_group_file, const Vector &p_files); bool _test_for_reimport(const String &p_path, bool p_only_imported_files); @@ -315,6 +315,7 @@ public: EditorFileSystemDirectory *find_file(const String &p_file, int *r_index) const; void reimport_files(const Vector &p_files); + Error reimport_append(const String &p_file, const HashMap &p_custom_options, const String &p_custom_importer = String()); void reimport_file_with_custom_parameters(const String &p_file, const String &p_importer, const HashMap &p_custom_params); diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index fb14dcf8884..0d387999ef3 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -31,6 +31,7 @@ #include "editor_import_plugin.h" #include "core/object/script_language.h" +#include "editor/editor_file_system.h" EditorImportPlugin::EditorImportPlugin() { } @@ -187,6 +188,20 @@ Error EditorImportPlugin::import(const String &p_source_file, const String &p_sa ERR_FAIL_V_MSG(ERR_METHOD_NOT_FOUND, "Unimplemented _import in add-on."); } +Error EditorImportPlugin::_append_import_external_resource(const String &p_file, const Dictionary &p_custom_options, const String &p_custom_importer) { + HashMap options; + List keys; + p_custom_options.get_key_list(&keys); + for (const Variant &K : keys) { + options.insert(K, p_custom_options[K]); + } + return append_import_external_resource(p_file, options, p_custom_importer); +} + +Error EditorImportPlugin::append_import_external_resource(const String &p_file, const HashMap &p_custom_options, const String &p_custom_importer) { + return EditorFileSystem::get_singleton()->reimport_append(p_file, p_custom_options, p_custom_importer); +} + void EditorImportPlugin::_bind_methods() { GDVIRTUAL_BIND(_get_importer_name) GDVIRTUAL_BIND(_get_visible_name) @@ -200,4 +215,5 @@ void EditorImportPlugin::_bind_methods() { GDVIRTUAL_BIND(_get_import_order) GDVIRTUAL_BIND(_get_option_visibility, "path", "option_name", "options") GDVIRTUAL_BIND(_import, "source_file", "save_path", "options", "platform_variants", "gen_files"); + ClassDB::bind_method(D_METHOD("append_import_external_resource", "path", "custom_options", "custom_importer"), &EditorImportPlugin::_append_import_external_resource, DEFVAL(Dictionary()), DEFVAL(String())); } diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 0f79ba4783c..8014bc54d55 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -53,6 +53,8 @@ protected: GDVIRTUAL3RC(bool, _get_option_visibility, String, StringName, Dictionary) GDVIRTUAL5RC(int, _import, String, String, Dictionary, TypedArray, TypedArray) + Error _append_import_external_resource(const String &p_file, const Dictionary &p_custom_options = Dictionary(), const String &p_custom_importer = String()); + public: EditorImportPlugin(); virtual String get_importer_name() const override; @@ -67,6 +69,7 @@ public: virtual void get_import_options(const String &p_path, List *r_options, int p_preset) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap &p_options) const override; virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap &p_options, List *r_platform_variants, List *r_gen_files, Variant *r_metadata = nullptr) override; + Error append_import_external_resource(const String &p_file, const HashMap &p_custom_options = HashMap(), const String &p_custom_importer = String()); }; #endif // EDITOR_IMPORT_PLUGIN_H