Merge pull request #92667 from Hilderin/fix-addon-requires-editor-restart
Fix Addon requires editor restart to become functional
This commit is contained in:
commit
866099684c
|
@ -35,6 +35,8 @@
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "core/variant/variant_parser.h"
|
#include "core/variant/variant_parser.h"
|
||||||
|
|
||||||
|
ResourceFormatImporterLoadOnStartup ResourceImporter::load_on_startup = nullptr;
|
||||||
|
|
||||||
bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const {
|
bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const {
|
||||||
return p_a->get_importer_name() < p_b->get_importer_name();
|
return p_a->get_importer_name() < p_b->get_importer_name();
|
||||||
}
|
}
|
||||||
|
@ -137,6 +139,20 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
|
Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
// When loading a resource on startup, we use the load_on_startup callback,
|
||||||
|
// which executes the loading in the EditorFileSystem. It can reimport
|
||||||
|
// the resource and retry the load, allowing the resource to be loaded
|
||||||
|
// even if it is not yet imported.
|
||||||
|
if (ResourceImporter::load_on_startup != nullptr) {
|
||||||
|
return ResourceImporter::load_on_startup(this, p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return load_internal(p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Resource> ResourceFormatImporter::load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors) {
|
||||||
PathAndType pat;
|
PathAndType pat;
|
||||||
Error err = _get_path_and_type(p_path, pat);
|
Error err = _get_path_and_type(p_path, pat);
|
||||||
|
|
||||||
|
@ -148,6 +164,13 @@ Ref<Resource> ResourceFormatImporter::load(const String &p_path, const String &p
|
||||||
return Ref<Resource>();
|
return Ref<Resource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_silence_errors) {
|
||||||
|
// Note: Some importers do not create files in the .godot folder, so we need to check if the path is empty.
|
||||||
|
if (!pat.path.is_empty() && !FileAccess::exists(pat.path)) {
|
||||||
|
return Ref<Resource>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Resource> res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress);
|
Ref<Resource> res = ResourceLoader::_load(pat.path, p_path, pat.type, p_cache_mode, r_error, p_use_sub_threads, r_progress);
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#include "core/io/resource_saver.h"
|
#include "core/io/resource_saver.h"
|
||||||
|
|
||||||
class ResourceImporter;
|
class ResourceImporter;
|
||||||
|
class ResourceFormatImporter;
|
||||||
|
|
||||||
|
typedef Ref<Resource> (*ResourceFormatImporterLoadOnStartup)(ResourceFormatImporter *p_importer, const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, ResourceFormatLoader::CacheMode p_cache_mode);
|
||||||
|
|
||||||
class ResourceFormatImporter : public ResourceFormatLoader {
|
class ResourceFormatImporter : public ResourceFormatLoader {
|
||||||
struct PathAndType {
|
struct PathAndType {
|
||||||
|
@ -60,6 +63,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
|
||||||
public:
|
public:
|
||||||
static ResourceFormatImporter *get_singleton() { return singleton; }
|
static ResourceFormatImporter *get_singleton() { return singleton; }
|
||||||
virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;
|
virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;
|
||||||
|
Ref<Resource> load_internal(const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode, bool p_silence_errors);
|
||||||
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
|
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
|
||||||
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const override;
|
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const override;
|
||||||
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const override;
|
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const override;
|
||||||
|
@ -94,6 +98,7 @@ public:
|
||||||
|
|
||||||
String get_import_base_path(const String &p_for_file) const;
|
String get_import_base_path(const String &p_for_file) const;
|
||||||
Error get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const;
|
Error get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const;
|
||||||
|
|
||||||
ResourceFormatImporter();
|
ResourceFormatImporter();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,6 +109,8 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static ResourceFormatImporterLoadOnStartup load_on_startup;
|
||||||
|
|
||||||
virtual String get_importer_name() const = 0;
|
virtual String get_importer_name() const = 0;
|
||||||
virtual String get_visible_name() const = 0;
|
virtual String get_visible_name() const = 0;
|
||||||
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
|
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/extension/gdextension_manager.h"
|
#include "core/extension/gdextension_manager.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
#include "core/io/resource_importer.h"
|
|
||||||
#include "core/io/resource_loader.h"
|
|
||||||
#include "core/io/resource_saver.h"
|
#include "core/io/resource_saver.h"
|
||||||
#include "core/object/worker_thread_pool.h"
|
#include "core/object/worker_thread_pool.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
@ -903,6 +901,7 @@ void EditorFileSystem::scan() {
|
||||||
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
||||||
// in editor_node to start the export if needed.
|
// in editor_node to start the export if needed.
|
||||||
first_scan = false;
|
first_scan = false;
|
||||||
|
ResourceImporter::load_on_startup = nullptr;
|
||||||
emit_signal(SNAME("filesystem_changed"));
|
emit_signal(SNAME("filesystem_changed"));
|
||||||
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
|
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1513,6 +1512,7 @@ void EditorFileSystem::_notification(int p_what) {
|
||||||
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
||||||
// in editor_node to start the export if needed.
|
// in editor_node to start the export if needed.
|
||||||
first_scan = false;
|
first_scan = false;
|
||||||
|
ResourceImporter::load_on_startup = nullptr;
|
||||||
if (changed) {
|
if (changed) {
|
||||||
emit_signal(SNAME("filesystem_changed"));
|
emit_signal(SNAME("filesystem_changed"));
|
||||||
}
|
}
|
||||||
|
@ -1535,6 +1535,7 @@ void EditorFileSystem::_notification(int p_what) {
|
||||||
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
// Set first_scan to false before the signals so the function doing_first_scan can return false
|
||||||
// in editor_node to start the export if needed.
|
// in editor_node to start the export if needed.
|
||||||
first_scan = false;
|
first_scan = false;
|
||||||
|
ResourceImporter::load_on_startup = nullptr;
|
||||||
emit_signal(SNAME("filesystem_changed"));
|
emit_signal(SNAME("filesystem_changed"));
|
||||||
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
|
emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
|
||||||
}
|
}
|
||||||
|
@ -2410,14 +2411,16 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<StringName, Variant> &p_custom_options, const String &p_custom_importer, Variant *p_generator_parameters) {
|
Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<StringName, Variant> &p_custom_options, const String &p_custom_importer, Variant *p_generator_parameters, bool p_update_file_system) {
|
||||||
print_verbose(vformat("EditorFileSystem: Importing file: %s", p_file));
|
print_verbose(vformat("EditorFileSystem: Importing file: %s", p_file));
|
||||||
uint64_t start_time = OS::get_singleton()->get_ticks_msec();
|
uint64_t start_time = OS::get_singleton()->get_ticks_msec();
|
||||||
|
|
||||||
EditorFileSystemDirectory *fs = nullptr;
|
EditorFileSystemDirectory *fs = nullptr;
|
||||||
int cpos = -1;
|
int cpos = -1;
|
||||||
bool found = _find_file(p_file, &fs, cpos);
|
if (p_update_file_system) {
|
||||||
ERR_FAIL_COND_V_MSG(!found, ERR_FILE_NOT_FOUND, "Can't find file '" + p_file + "'.");
|
bool found = _find_file(p_file, &fs, cpos);
|
||||||
|
ERR_FAIL_COND_V_MSG(!found, ERR_FILE_NOT_FOUND, "Can't find file '" + p_file + "'.");
|
||||||
|
}
|
||||||
|
|
||||||
//try to obtain existing params
|
//try to obtain existing params
|
||||||
|
|
||||||
|
@ -2471,11 +2474,13 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin
|
||||||
|
|
||||||
if (importer_name == "keep" || importer_name == "skip") {
|
if (importer_name == "keep" || importer_name == "skip") {
|
||||||
//keep files, do nothing.
|
//keep files, do nothing.
|
||||||
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
if (p_update_file_system) {
|
||||||
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
|
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
||||||
fs->files[cpos]->deps.clear();
|
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
|
||||||
fs->files[cpos]->type = "";
|
fs->files[cpos]->deps.clear();
|
||||||
fs->files[cpos]->import_valid = false;
|
fs->files[cpos]->type = "";
|
||||||
|
fs->files[cpos]->import_valid = false;
|
||||||
|
}
|
||||||
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
|
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -2635,16 +2640,18 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update cpos, newly created files could've changed the index of the reimported p_file.
|
if (p_update_file_system) {
|
||||||
_find_file(p_file, &fs, cpos);
|
// Update cpos, newly created files could've changed the index of the reimported p_file.
|
||||||
|
_find_file(p_file, &fs, cpos);
|
||||||
|
|
||||||
// Update modified times, to avoid reimport.
|
// Update modified times, to avoid reimport.
|
||||||
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
||||||
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
|
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
|
||||||
fs->files[cpos]->deps = _get_dependencies(p_file);
|
fs->files[cpos]->deps = _get_dependencies(p_file);
|
||||||
fs->files[cpos]->type = importer->get_resource_type();
|
fs->files[cpos]->type = importer->get_resource_type();
|
||||||
fs->files[cpos]->uid = uid;
|
fs->files[cpos]->uid = uid;
|
||||||
fs->files[cpos]->import_valid = fs->files[cpos]->type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file);
|
fs->files[cpos]->import_valid = fs->files[cpos]->type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file);
|
||||||
|
}
|
||||||
|
|
||||||
if (ResourceUID::get_singleton()->has_id(uid)) {
|
if (ResourceUID::get_singleton()->has_id(uid)) {
|
||||||
ResourceUID::get_singleton()->set_id(uid, p_file);
|
ResourceUID::get_singleton()->set_id(uid, p_file);
|
||||||
|
@ -2904,6 +2911,33 @@ Error EditorFileSystem::_resource_import(const String &p_path) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<Resource> EditorFileSystem::_load_resource_on_startup(ResourceFormatImporter *p_importer, const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, ResourceFormatLoader::CacheMode p_cache_mode) {
|
||||||
|
ERR_FAIL_NULL_V(p_importer, Ref<Resource>());
|
||||||
|
|
||||||
|
if (!FileAccess::exists(p_path)) {
|
||||||
|
ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Failed loading resource: %s. The file doesn't seem to exist.", p_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Resource> res;
|
||||||
|
bool can_retry = true;
|
||||||
|
bool retry = true;
|
||||||
|
while (retry) {
|
||||||
|
retry = false;
|
||||||
|
|
||||||
|
res = p_importer->load_internal(p_path, r_error, p_use_sub_threads, r_progress, p_cache_mode, can_retry);
|
||||||
|
|
||||||
|
if (res.is_null() && can_retry) {
|
||||||
|
can_retry = false;
|
||||||
|
Error err = singleton->_reimport_file(p_path, HashMap<StringName, Variant>(), "", nullptr, false);
|
||||||
|
if (err == OK) {
|
||||||
|
retry = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorFileSystem::_should_skip_directory(const String &p_path) {
|
bool EditorFileSystem::_should_skip_directory(const String &p_path) {
|
||||||
String project_data_path = ProjectSettings::get_singleton()->get_project_data_path();
|
String project_data_path = ProjectSettings::get_singleton()->get_project_data_path();
|
||||||
if (p_path == project_data_path || p_path.begins_with(project_data_path + "/")) {
|
if (p_path == project_data_path || p_path.begins_with(project_data_path + "/")) {
|
||||||
|
@ -3101,6 +3135,10 @@ EditorFileSystem::EditorFileSystem() {
|
||||||
|
|
||||||
scan_total = 0;
|
scan_total = 0;
|
||||||
ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
|
ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
|
||||||
|
|
||||||
|
// Set the callback method that the ResourceFormatImporter will use
|
||||||
|
// if resources are loaded during the first scan.
|
||||||
|
ResourceImporter::load_on_startup = _load_resource_on_startup;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorFileSystem::~EditorFileSystem() {
|
EditorFileSystem::~EditorFileSystem() {
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#define EDITOR_FILE_SYSTEM_H
|
#define EDITOR_FILE_SYSTEM_H
|
||||||
|
|
||||||
#include "core/io/dir_access.h"
|
#include "core/io/dir_access.h"
|
||||||
|
#include "core/io/resource_importer.h"
|
||||||
|
#include "core/io/resource_loader.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
#include "core/os/thread_safe.h"
|
#include "core/os/thread_safe.h"
|
||||||
#include "core/templates/hash_set.h"
|
#include "core/templates/hash_set.h"
|
||||||
|
@ -252,7 +254,7 @@ class EditorFileSystem : public Node {
|
||||||
|
|
||||||
void _update_extensions();
|
void _update_extensions();
|
||||||
|
|
||||||
Error _reimport_file(const String &p_file, const HashMap<StringName, Variant> &p_custom_options = HashMap<StringName, Variant>(), const String &p_custom_importer = String(), Variant *generator_parameters = nullptr);
|
Error _reimport_file(const String &p_file, const HashMap<StringName, Variant> &p_custom_options = HashMap<StringName, Variant>(), const String &p_custom_importer = String(), Variant *generator_parameters = nullptr, bool p_update_file_system = true);
|
||||||
Error _reimport_group(const String &p_group_file, const Vector<String> &p_files);
|
Error _reimport_group(const String &p_group_file, const Vector<String> &p_files);
|
||||||
|
|
||||||
bool _test_for_reimport(const String &p_path, bool p_only_imported_files);
|
bool _test_for_reimport(const String &p_path, bool p_only_imported_files);
|
||||||
|
@ -296,6 +298,7 @@ class EditorFileSystem : public Node {
|
||||||
String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
|
String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
|
||||||
|
|
||||||
static Error _resource_import(const String &p_path);
|
static Error _resource_import(const String &p_path);
|
||||||
|
static Ref<Resource> _load_resource_on_startup(ResourceFormatImporter *p_importer, const String &p_path, Error *r_error, bool p_use_sub_threads, float *r_progress, ResourceFormatLoader::CacheMode p_cache_mode);
|
||||||
|
|
||||||
bool using_fat32_or_exfat; // Workaround for projects in FAT32 or exFAT filesystem (pendrives, most of the time)
|
bool using_fat32_or_exfat; // Workaround for projects in FAT32 or exFAT filesystem (pendrives, most of the time)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue