diff options
-rw-r--r-- | editor/editor_node.cpp | 33 | ||||
-rw-r--r-- | editor/editor_node.h | 4 | ||||
-rw-r--r-- | editor/surface_upgrade_tool.cpp | 121 | ||||
-rw-r--r-- | editor/surface_upgrade_tool.h | 26 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 8 |
5 files changed, 156 insertions, 36 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6d28b9abc8..d17a1ccecc 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -623,6 +623,20 @@ void EditorNode::_notification(int p_what) { ResourceImporterTexture::get_singleton()->update_imports(); bottom_panel_updating = false; + + if (requested_first_scan) { + requested_first_scan = false; + + OS::get_singleton()->benchmark_begin_measure("editor_scan_and_import"); + + if (run_surface_upgrade_tool) { + run_surface_upgrade_tool = false; + SurfaceUpgradeTool::get_singleton()->connect("upgrade_finished", callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::scan), CONNECT_ONE_SHOT); + SurfaceUpgradeTool::get_singleton()->finish_upgrade(); + } else { + EditorFileSystem::get_singleton()->scan(); + } + } } break; case NOTIFICATION_ENTER_TREE: { @@ -1042,6 +1056,10 @@ void EditorNode::_sources_changed(bool p_exist) { OS::get_singleton()->benchmark_dump(); } + + if (SurfaceUpgradeTool::get_singleton()->is_show_requested()) { + SurfaceUpgradeTool::get_singleton()->show_popup(); + } } } @@ -4615,8 +4633,10 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) { Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; void EditorNode::_begin_first_scan() { - OS::get_singleton()->benchmark_begin_measure("editor_scan_and_import"); - EditorFileSystem::get_singleton()->scan(); + if (!waiting_for_first_scan) { + return; + } + requested_first_scan = true; } Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only) { @@ -6809,6 +6829,13 @@ EditorNode::EditorNode() { FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); + // Warm up the surface upgrade tool as early as possible. + surface_upgrade_tool = memnew(SurfaceUpgradeTool); + run_surface_upgrade_tool = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "run_on_restart", false); + if (run_surface_upgrade_tool) { + SurfaceUpgradeTool::get_singleton()->begin_upgrade(); + } + { int display_scale = EDITOR_GET("interface/editor/display_scale"); @@ -8051,8 +8078,6 @@ EditorNode::EditorNode() { String exec = OS::get_singleton()->get_executable_path(); // Save editor executable path for third-party tools. EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "executable_path", exec); - - surface_upgrade_tool = memnew(SurfaceUpgradeTool); } EditorNode::~EditorNode() { diff --git a/editor/editor_node.h b/editor/editor_node.h index b2fb03be6b..fe99cf1f01 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -157,6 +157,7 @@ public: private: friend class EditorSceneTabs; + friend class SurfaceUpgradeTool; enum MenuOptions { FILE_NEW_SCENE, @@ -459,6 +460,8 @@ private: bool opening_prev = false; bool restoring_scenes = false; bool unsaved_cache = true; + + bool requested_first_scan = false; bool waiting_for_first_scan = true; int current_menu_option = 0; @@ -493,6 +496,7 @@ private: HashMap<String, Ref<Texture2D>> icon_type_cache; SurfaceUpgradeTool *surface_upgrade_tool = nullptr; + bool run_surface_upgrade_tool = false; static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS]; 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() {} diff --git a/editor/surface_upgrade_tool.h b/editor/surface_upgrade_tool.h index fa052200d8..70e07c58a1 100644 --- a/editor/surface_upgrade_tool.h +++ b/editor/surface_upgrade_tool.h @@ -35,13 +35,31 @@ class EditorFileSystemDirectory; -class SurfaceUpgradeTool { - static void upgrade_all_meshes(); +class SurfaceUpgradeTool : public Object { + GDCLASS(SurfaceUpgradeTool, Object); - static void _show_popup(); - static void _add_files(EditorFileSystemDirectory *p_dir, HashSet<String> &r_paths, PackedStringArray &r_files); + static SurfaceUpgradeTool *singleton; + + bool show_requested = false; + bool popped_up = false; + Mutex mutex; + + static void _try_show_popup(); + void _show_popup(); + void _add_files(EditorFileSystemDirectory *p_dir, Vector<String> &r_reimport_paths, Vector<String> &r_resave_paths); + +protected: + static void _bind_methods(); public: + static SurfaceUpgradeTool *get_singleton() { return singleton; }; + + bool is_show_requested() const { return show_requested; }; + void show_popup() { _show_popup(); } + + void begin_upgrade(); + void finish_upgrade(); + SurfaceUpgradeTool(); ~SurfaceUpgradeTool(); }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index eb940cdd56..78b5656a74 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2076,10 +2076,10 @@ void RenderingServer::fix_surface_compatibility(SurfaceData &p_surface, const St } if (warn_on_surface_upgrade) { - if (p_path.is_empty()) { - WARN_PRINT("A surface uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); - } else { - WARN_PRINT("A surface of " + p_path + " uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); + WARN_PRINT_ONCE_ED("At least one surface uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); + + if (!p_path.is_empty()) { + WARN_PRINT("A surface of " + p_path + " uses an old surface format and needs to be upgraded."); } } #endif |