You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Overhaul the SurfaceUpgradeTool
This defers the update to a fresh restart of the editor (to ensure we aren't mid way through loading scenes anymore. It also ensures that the popup can't be used by multiple threads at once Co-authored-by: Yuri Sizov <yuris@humnom.net>
This commit is contained in:
@@ -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() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
void SurfaceUpgradeTool::finish_upgrade() {
|
||||
EditorNode::get_singleton()->trigger_menu_option(EditorNode::FILE_CLOSE_ALL, true);
|
||||
|
||||
// Update all meshes here.
|
||||
HashSet<String> paths;
|
||||
PackedStringArray files_to_import;
|
||||
_add_files(EditorFileSystem::get_singleton()->get_filesystem(), paths, files_to_import);
|
||||
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());
|
||||
|
||||
EditorProgress ep("Re-saving all scenes and meshes", TTR("Upgrading All Meshes in Project"), paths.size());
|
||||
|
||||
ep.step(TTR("Re-importing meshes"), 0);
|
||||
EditorFileSystem::get_singleton()->reimport_files(files_to_import);
|
||||
|
||||
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>());
|
||||
|
||||
// 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::_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();
|
||||
}
|
||||
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() {}
|
||||
|
||||
Reference in New Issue
Block a user