diff options
Diffstat (limited to 'editor/surface_upgrade_tool.cpp')
-rw-r--r-- | editor/surface_upgrade_tool.cpp | 121 |
1 files changed, 97 insertions, 24 deletions
diff --git a/editor/surface_upgrade_tool.cpp b/editor/surface_upgrade_tool.cpp index 26ff6e55a0..31834ed0c4 100644 --- a/editor/surface_upgrade_tool.cpp +++ b/editor/surface_upgrade_tool.cpp @@ -32,11 +32,15 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "scene/scene_string_names.h" #include "servers/rendering_server.h" -void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, HashSet<String> &r_paths, PackedStringArray &r_files) { +SurfaceUpgradeTool *SurfaceUpgradeTool::singleton = nullptr; + +void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, Vector<String> &r_reimport_paths, Vector<String> &r_resave_paths) { for (int i = 0; i < p_dir->get_subdir_count(); i++) { - _add_files(p_dir->get_subdir(i), r_paths, r_files); + _add_files(p_dir->get_subdir(i), r_reimport_paths, r_resave_paths); } for (int i = 0; i < p_dir->get_file_count(); i++) { @@ -44,47 +48,116 @@ void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, HashSet<St p_dir->get_file_type(i) == "ArrayMesh" || p_dir->get_file_type(i) == "PackedScene") { if (FileAccess::exists(p_dir->get_file_path(i) + ".import")) { - r_files.push_back(p_dir->get_file_path(i)); + r_reimport_paths.append(p_dir->get_file_path(i) + ".import"); } else { - r_paths.insert(p_dir->get_file_path(i)); + r_resave_paths.append(p_dir->get_file_path(i)); } } } } -void SurfaceUpgradeTool::upgrade_all_meshes() { - // Update all meshes here. - HashSet<String> paths; - PackedStringArray files_to_import; - _add_files(EditorFileSystem::get_singleton()->get_filesystem(), paths, files_to_import); +void SurfaceUpgradeTool::_try_show_popup() { + if (singleton->show_requested || singleton->popped_up) { + return; + } + singleton->show_requested = true; + + RS::get_singleton()->set_warn_on_surface_upgrade(false); + + if (EditorFileSystem::get_singleton()->is_importing()) { + EditorFileSystem::get_singleton()->connect("resources_reimported", callable_mp(singleton, &SurfaceUpgradeTool::_show_popup), CONNECT_ONE_SHOT); + } else if (EditorNode::get_singleton()->is_inside_tree()) { + singleton->_show_popup(); + } + + // EditorNode may not be ready yet. It will call this tool when it is. +} + +void SurfaceUpgradeTool::_show_popup() { + MutexLock lock(mutex); + if (!show_requested || popped_up) { + return; + } + show_requested = false; + popped_up = true; + + bool accepted = EditorNode::immediate_confirmation_dialog(TTR("This project uses meshes with an outdated mesh format from previous Godot versions. The engine needs to update the format in order to use those meshes.\n\nPress 'Restart & Upgrade' to run the surface upgrade tool which will update and re-save all meshes and scenes. This update will restart the editor and may take several minutes. Upgrading will make the meshes incompatible with previous versions of Godot.\n\nPress 'Upgrade Only' to continue opening the scene as normal. The engine will update each mesh in memory, but the update will not be saved. Choosing this option will lead to slower load times every time this project is loaded."), TTR("Restart & Upgrade"), TTR("Upgrade Only"), 500); + if (accepted) { + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "run_on_restart", true); + + Vector<String> reimport_paths; + Vector<String> resave_paths; + _add_files(EditorFileSystem::get_singleton()->get_filesystem(), reimport_paths, resave_paths); + + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "reimport_paths", reimport_paths); + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "resave_paths", resave_paths); + + EditorNode::get_singleton()->restart_editor(); + } else { + RS::get_singleton()->set_warn_on_surface_upgrade(true); + } +} - EditorProgress ep("Re-saving all scenes and meshes", TTR("Upgrading All Meshes in Project"), paths.size()); +// Ensure that the warnings and popups are skipped. +void SurfaceUpgradeTool::begin_upgrade() { + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "run_on_restart", false); + RS::get_singleton()->set_surface_upgrade_callback(nullptr); + RS::get_singleton()->set_warn_on_surface_upgrade(false); + popped_up = true; +} - ep.step(TTR("Re-importing meshes"), 0); - EditorFileSystem::get_singleton()->reimport_files(files_to_import); +void SurfaceUpgradeTool::finish_upgrade() { + EditorNode::get_singleton()->trigger_menu_option(EditorNode::FILE_CLOSE_ALL, true); + + // Update all meshes here. + Vector<String> resave_paths = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "resave_paths", Vector<String>()); + EditorProgress ep("surface_upgrade_resave", TTR("Upgrading All Meshes in Project"), resave_paths.size()); - uint32_t step = 1; - for (const String &file : paths) { - Ref<Resource> res = ResourceLoader::load(file); - ep.step(TTR("Attempting to re-save ") + file, step++); + for (const String &file_path : resave_paths) { + Ref<Resource> res = ResourceLoader::load(file_path); + ep.step(TTR("Attempting to re-save ") + file_path); if (res.is_valid()) { // Ignore things that fail to load. ResourceSaver::save(res); } } -} + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "resave_paths", Vector<String>()); -void SurfaceUpgradeTool::_show_popup() { - RS::get_singleton()->set_surface_upgrade_callback(nullptr); - bool accepted = EditorNode::immediate_confirmation_dialog(TTR("This project uses meshes with an outdated mesh format from previous Godot versions. The engine needs to update the format in order to use those meshes.\n\nPress 'Upgrade & Re-save' to have the engine scan the project folder and automatically update and re-save all meshes and scenes. This update may take a few minutes. Upgrading will make the meshes incompatible with previous versions of Godot.\n\nPress 'Upgrade Only' to continue opening the scene as normal. The engine will update each mesh in memory, but the update will not be saved. Choosing this option will lead to slower load times every time this project is loaded."), TTR("Upgrade & Re-save"), TTR("Upgrade Only"), 500); - if (accepted) { - RS::get_singleton()->set_warn_on_surface_upgrade(false); - upgrade_all_meshes(); + // Remove the imported scenes/meshes from .import so they will be reimported automatically after this. + Vector<String> reimport_paths = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "reimport_paths", Vector<String>()); + for (const String &file_path : reimport_paths) { + Ref<ConfigFile> config; + config.instantiate(); + Error err = config->load(file_path); + if (err != OK) { + ERR_PRINT("Could not open " + file_path + " for upgrade."); + continue; + } + + String remap_path = config->get_value("remap", "path", ""); + if (remap_path.is_empty()) { + continue; + } + + String path = OS::get_singleton()->get_resource_dir() + remap_path.replace_first("res://", "/"); + print_verbose("Moving to trash: " + path); + err = OS::get_singleton()->move_to_trash(path); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + remap_path + "\n"); + } } + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "reimport_paths", Vector<String>()); + + emit_signal(SNAME("upgrade_finished")); +} + +void SurfaceUpgradeTool::_bind_methods() { + ADD_SIGNAL(MethodInfo("upgrade_finished")); } SurfaceUpgradeTool::SurfaceUpgradeTool() { - RS::get_singleton()->set_surface_upgrade_callback(_show_popup); + singleton = this; + RS::get_singleton()->set_surface_upgrade_callback(_try_show_popup); } SurfaceUpgradeTool::~SurfaceUpgradeTool() {} |