From 8e6596629a7e239bb3b8008b96554850d5688233 Mon Sep 17 00:00:00 2001 From: Allen Pestaluky Date: Tue, 2 Jul 2024 12:55:29 -0400 Subject: [PATCH] EditorExportPlugin: Call _export_file for all resource types - Alternate fix to #67844 that calls `_export_file` for all resource types instead of implementing `skip()` for customize functions. - Fixes #93823. - Moved logic surrounding "Skip" and "Keep" imported files to happen before resource customization. Fixes #93825. - Also fixes an issue that I suspect might exist where progress bars during export were incorrect due to imported files in the project that are configured as "Keep" or "Skip". --- doc/classes/EditorExportPlugin.xml | 6 +- editor/export/editor_export_platform.cpp | 181 +++++++++++------------ 2 files changed, 92 insertions(+), 95 deletions(-) diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index bcc5745aa5b..9ef911a68dc 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -36,7 +36,6 @@ Customize a resource. If changes are made to it, return the same or a new resource. Otherwise, return [code]null[/code]. The [i]path[/i] argument is only used when customizing an actual file, otherwise this means that this resource is part of another one and it will be empty. - Calling [method skip] inside this callback will make the file not included in the export. Implementing this method is required if [method _begin_customize_resources] returns [code]true[/code]. @@ -46,7 +45,6 @@ Customize a scene. If changes are made to it, return the same or a new scene. Otherwise, return [code]null[/code]. If a new scene is returned, it is up to you to dispose of the old one. - Calling [method skip] inside this callback will make the file not included in the export. Implementing this method is required if [method _begin_customize_scenes] returns [code]true[/code]. @@ -84,9 +82,8 @@ - Virtual method to be overridden by the user. Called for each exported file, except for imported resources (resources that have an associated [code].import[/code] file). The arguments can be used to identify the file. [param path] is the path of the file, [param type] is the [Resource] represented by the file (e.g. [PackedScene]), and [param features] is the list of features for the export. + Virtual method to be overridden by the user. Called for each exported file before [method _customize_resource] and [method _customize_scene]. The arguments can be used to identify the file. [param path] is the path of the file, [param type] is the [Resource] represented by the file (e.g. [PackedScene]), and [param features] is the list of features for the export. Calling [method skip] inside this callback will make the file not included in the export. - Use [method _customize_resource] for imported resources that are not handled by this function. @@ -235,6 +232,7 @@ Adds a custom file to be exported. [param path] is the virtual path that can be used to load the file, [param file] is the binary data of the file. When called inside [method _export_file] and [param remap] is [code]true[/code], the current file will not be exported, but instead remapped to this custom file. [param remap] is ignored when called in other places. + [param file] will not be imported, so consider using [method _customize_resource] to remap imported resources. diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 7417ff48c60..c0646dc572c 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -1124,29 +1124,97 @@ Error EditorExportPlatform::export_project_files(const Ref & } //store everything in the export medium - int idx = 0; int total = paths.size(); + // idx is incremented at the beginning of the paths loop to easily allow + // for continue statements without accidentally skipping an increment. + int idx = total > 0 ? -1 : 0; for (const String &E : paths) { + idx++; String path = E; String type = ResourceLoader::get_resource_type(path); - if (FileAccess::exists(path + ".import")) { - // Before doing this, try to see if it can be customized. + bool has_import_file = FileAccess::exists(path + ".import"); + Ref config; + if (has_import_file) { + config.instantiate(); + err = config->load(path + ".import"); + if (err != OK) { + ERR_PRINT("Could not parse: '" + path + "', not exported."); + continue; + } + String importer_type = config->get_value("remap", "importer"); + + if (importer_type == "skip") { + // Skip file. + continue; + } + } + + bool do_export = true; + for (int i = 0; i < export_plugins.size(); i++) { + if (GDVIRTUAL_IS_OVERRIDDEN_PTR(export_plugins[i], _export_file)) { + export_plugins.write[i]->_export_file_script(path, type, features_psa); + } else { + export_plugins.write[i]->_export_file(path, type, features); + } + if (p_so_func) { + for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) { + err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]); + if (err != OK) { + return err; + } + } + } + + for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { + err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; + } + if (export_plugins[i]->extra_files[j].remap) { + do_export = false; // If remap, do not. + path_remaps.push_back(path); + path_remaps.push_back(export_plugins[i]->extra_files[j].path); + } + } + + if (export_plugins[i]->skipped) { + do_export = false; + } + export_plugins.write[i]->_clear(); + + if (!do_export) { + break; + } + } + if (!do_export) { + continue; + } + + if (has_import_file) { + String importer_type = config->get_value("remap", "importer"); + + if (importer_type == "keep") { + // Just keep file as-is. + Vector array = FileAccess::get_file_as_bytes(path); + err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + + if (err != OK) { + return err; + } + + continue; + } + + // Before doing this, try to see if it can be customized. String export_path = _export_customize(path, customize_resources_plugins, customize_scenes_plugins, export_cache, export_base_path, false); if (export_path != path) { // It was actually customized. // Since the original file is likely not recognized, just use the import system. - Ref config; - config.instantiate(); - err = config->load(path + ".import"); - if (err != OK) { - ERR_PRINT("Could not parse: '" + path + "', not exported."); - continue; - } config->set_value("remap", "type", ResourceLoader::get_resource_type(export_path)); // Erase all Paths. @@ -1182,33 +1250,6 @@ Error EditorExportPlatform::export_project_files(const Ref & } } else { // File is imported and not customized, replace by what it imports. - Ref config; - config.instantiate(); - err = config->load(path + ".import"); - if (err != OK) { - ERR_PRINT("Could not parse: '" + path + "', not exported."); - continue; - } - - String importer_type = config->get_value("remap", "importer"); - - if (importer_type == "skip") { - // Skip file. - continue; - } - - if (importer_type == "keep") { - // Just keep file as-is. - Vector array = FileAccess::get_file_as_bytes(path); - err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); - - if (err != OK) { - return err; - } - - continue; - } - List remaps; config->get_section_keys("remap", &remaps); @@ -1270,66 +1311,24 @@ Error EditorExportPlatform::export_project_files(const Ref & } } else { - // Customize. + // Just store it as it comes. - bool do_export = true; - for (int i = 0; i < export_plugins.size(); i++) { - if (GDVIRTUAL_IS_OVERRIDDEN_PTR(export_plugins[i], _export_file)) { - export_plugins.write[i]->_export_file_script(path, type, features_psa); - } else { - export_plugins.write[i]->_export_file(path, type, features); - } - if (p_so_func) { - for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) { - err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]); - if (err != OK) { - return err; - } - } - } + // Customization only happens if plugins did not take care of it before. + bool force_binary = convert_text_to_binary && (path.get_extension().to_lower() == "tres" || path.get_extension().to_lower() == "tscn"); + String export_path = _export_customize(path, customize_resources_plugins, customize_scenes_plugins, export_cache, export_base_path, force_binary); - for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { - err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key); - if (err != OK) { - return err; - } - if (export_plugins[i]->extra_files[j].remap) { - do_export = false; //if remap, do not - path_remaps.push_back(path); - path_remaps.push_back(export_plugins[i]->extra_files[j].path); - } - } - - if (export_plugins[i]->skipped) { - do_export = false; - } - export_plugins.write[i]->_clear(); - - if (!do_export) { - break; //apologies, not exporting - } + if (export_path != path) { + // Add a remap entry. + path_remaps.push_back(path); + path_remaps.push_back(export_path); } - //just store it as it comes - if (do_export) { - // Customization only happens if plugins did not take care of it before - bool force_binary = convert_text_to_binary && (path.get_extension().to_lower() == "tres" || path.get_extension().to_lower() == "tscn"); - String export_path = _export_customize(path, customize_resources_plugins, customize_scenes_plugins, export_cache, export_base_path, force_binary); - if (export_path != path) { - // Add a remap entry - path_remaps.push_back(path); - path_remaps.push_back(export_path); - } - - Vector array = FileAccess::get_file_as_bytes(export_path); - err = p_func(p_udata, export_path, array, idx, total, enc_in_filters, enc_ex_filters, key); - if (err != OK) { - return err; - } + Vector array = FileAccess::get_file_as_bytes(export_path); + err = p_func(p_udata, export_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + if (err != OK) { + return err; } } - - idx++; } if (convert_text_to_binary || !customize_resources_plugins.is_empty() || !customize_scenes_plugins.is_empty()) {