Merge pull request #92303 from Hilderin/fix-synchronization-global-class-name
Fix synchronization of global class name
This commit is contained in:
@@ -55,11 +55,6 @@ void EditorAutoloadSettings::_notification(int p_what) {
|
||||
file_dialog->add_filter("*." + E);
|
||||
}
|
||||
|
||||
for (const AutoloadInfo &info : autoload_cache) {
|
||||
if (info.node && info.in_editor) {
|
||||
callable_mp((Node *)get_tree()->get_root(), &Node::add_child).call_deferred(info.node, false, Node::INTERNAL_MODE_DISABLED);
|
||||
}
|
||||
}
|
||||
browse_button->set_icon(get_editor_theme_icon(SNAME("Folder")));
|
||||
} break;
|
||||
|
||||
@@ -419,6 +414,8 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
|
||||
|
||||
Ref<Script> scr = res;
|
||||
if (scr.is_valid()) {
|
||||
ERR_FAIL_COND_V_MSG(!scr->is_valid(), nullptr, vformat("Failed to create an autoload, script '%s' is not compiling.", p_path));
|
||||
|
||||
StringName ibt = scr->get_instance_base_type();
|
||||
bool valid_type = ClassDB::is_parent_class(ibt, "Node");
|
||||
ERR_FAIL_COND_V_MSG(!valid_type, nullptr, vformat("Failed to create an autoload, script '%s' does not inherit from 'Node'.", p_path));
|
||||
@@ -436,6 +433,35 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
|
||||
return n;
|
||||
}
|
||||
|
||||
void EditorAutoloadSettings::init_autoloads() {
|
||||
for (AutoloadInfo &info : autoload_cache) {
|
||||
info.node = _create_autoload(info.path);
|
||||
|
||||
if (info.node) {
|
||||
Ref<Script> scr = info.node->get_script();
|
||||
info.in_editor = scr.is_valid() && scr->is_tool();
|
||||
info.node->set_name(info.name);
|
||||
}
|
||||
|
||||
if (info.is_singleton) {
|
||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||
ScriptServer::get_language(i)->add_named_global_constant(info.name, info.node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!info.is_singleton && !info.in_editor && info.node != nullptr) {
|
||||
memdelete(info.node);
|
||||
info.node = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (const AutoloadInfo &info : autoload_cache) {
|
||||
if (info.node && info.in_editor) {
|
||||
callable_mp((Node *)get_tree()->get_root(), &Node::add_child).call_deferred(info.node, false, Node::INTERNAL_MODE_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorAutoloadSettings::update_autoload() {
|
||||
if (updating_autoload) {
|
||||
return;
|
||||
@@ -857,27 +883,6 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
|
||||
autoload_cache.push_back(info);
|
||||
}
|
||||
|
||||
for (AutoloadInfo &info : autoload_cache) {
|
||||
info.node = _create_autoload(info.path);
|
||||
|
||||
if (info.node) {
|
||||
Ref<Script> scr = info.node->get_script();
|
||||
info.in_editor = scr.is_valid() && scr->is_tool();
|
||||
info.node->set_name(info.name);
|
||||
}
|
||||
|
||||
if (info.is_singleton) {
|
||||
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
|
||||
ScriptServer::get_language(i)->add_named_global_constant(info.name, info.node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!info.is_singleton && !info.in_editor && info.node != nullptr) {
|
||||
memdelete(info.node);
|
||||
info.node = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HBoxContainer *hbc = memnew(HBoxContainer);
|
||||
add_child(hbc);
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void init_autoloads();
|
||||
void update_autoload();
|
||||
bool autoload_add(const String &p_name, const String &p_path);
|
||||
void autoload_remove(const String &p_name);
|
||||
|
||||
+342
-143
File diff suppressed because it is too large
Load Diff
@@ -159,11 +159,21 @@ class EditorFileSystem : public Node {
|
||||
EditorFileSystemDirectory::FileInfo *new_file = nullptr;
|
||||
};
|
||||
|
||||
struct ScannedDirectory {
|
||||
String name;
|
||||
String full_path;
|
||||
Vector<ScannedDirectory *> subdirs;
|
||||
List<String> files;
|
||||
|
||||
~ScannedDirectory();
|
||||
};
|
||||
|
||||
bool use_threads = false;
|
||||
Thread thread;
|
||||
static void _thread_func(void *_userdata);
|
||||
|
||||
EditorFileSystemDirectory *new_filesystem = nullptr;
|
||||
ScannedDirectory *first_scan_root_dir = nullptr;
|
||||
|
||||
bool scanning = false;
|
||||
bool importing = false;
|
||||
@@ -172,8 +182,11 @@ class EditorFileSystem : public Node {
|
||||
float scan_total;
|
||||
String filesystem_settings_version_for_import;
|
||||
bool revalidate_import_files = false;
|
||||
int nb_files_total = 0;
|
||||
|
||||
void _scan_filesystem();
|
||||
void _first_scan_filesystem();
|
||||
void _first_scan_process_scripts(const ScannedDirectory *p_scan_dir, HashSet<String> &p_existing_class_names);
|
||||
|
||||
HashSet<String> late_update_files;
|
||||
|
||||
@@ -202,11 +215,10 @@ class EditorFileSystem : public Node {
|
||||
HashSet<String> dep_update_list;
|
||||
|
||||
struct ScanProgress {
|
||||
float low = 0;
|
||||
float hi = 0;
|
||||
mutable EditorProgressBG *progress = nullptr;
|
||||
void update(int p_current, int p_total) const;
|
||||
ScanProgress get_sub(int p_current, int p_total) const;
|
||||
int current = 0;
|
||||
EditorProgressBG *progress = nullptr;
|
||||
void increment();
|
||||
};
|
||||
|
||||
void _save_filesystem_cache();
|
||||
@@ -214,15 +226,17 @@ class EditorFileSystem : public Node {
|
||||
|
||||
bool _find_file(const String &p_file, EditorFileSystemDirectory **r_d, int &r_file_pos) const;
|
||||
|
||||
void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress);
|
||||
void _scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanProgress &p_progress);
|
||||
|
||||
void _delete_internal_files(const String &p_file);
|
||||
int _insert_actions_delete_files_directory(EditorFileSystemDirectory *p_dir);
|
||||
|
||||
HashSet<String> textfile_extensions;
|
||||
HashSet<String> valid_extensions;
|
||||
HashSet<String> import_extensions;
|
||||
|
||||
void _scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAccess> &da, const ScanProgress &p_progress);
|
||||
int _scan_new_dir(ScannedDirectory *p_dir, Ref<DirAccess> &da);
|
||||
void _process_file_system(const ScannedDirectory *p_scan_dir, EditorFileSystemDirectory *p_dir, ScanProgress &p_progress);
|
||||
|
||||
Thread thread_sources;
|
||||
bool scanning_changes = false;
|
||||
@@ -256,11 +270,20 @@ class EditorFileSystem : public Node {
|
||||
}
|
||||
};
|
||||
|
||||
struct ScriptInfo {
|
||||
String type;
|
||||
String script_class_name;
|
||||
String script_class_extends;
|
||||
String script_class_icon_path;
|
||||
};
|
||||
|
||||
Mutex update_script_mutex;
|
||||
HashSet<String> update_script_paths;
|
||||
void _queue_update_script_class(const String &p_path);
|
||||
HashMap<String, ScriptInfo> update_script_paths;
|
||||
HashSet<String> update_script_paths_documentation;
|
||||
void _queue_update_script_class(const String &p_path, const String &p_type, const String &p_script_class_name, const String &p_script_class_extends, const String &p_script_class_icon_path);
|
||||
void _update_script_classes();
|
||||
void _update_pending_script_classes();
|
||||
void _update_script_documentation();
|
||||
void _process_update_pending();
|
||||
|
||||
Mutex update_scene_mutex;
|
||||
HashSet<String> update_scene_paths;
|
||||
@@ -300,6 +323,10 @@ class EditorFileSystem : public Node {
|
||||
|
||||
void _update_file_icon_path(EditorFileSystemDirectory::FileInfo *file_info);
|
||||
void _update_files_icon_path(EditorFileSystemDirectory *edp = nullptr);
|
||||
void _remove_invalid_global_class_names(const HashSet<String> &p_existing_class_names);
|
||||
String _get_file_by_class_name(EditorFileSystemDirectory *p_dir, const String &p_class_name, EditorFileSystemDirectory::FileInfo *&r_file_info);
|
||||
|
||||
void _register_global_class_script(const String &p_search_path, const String &p_target_path, const String &p_type, const String &p_script_class_name, const String &p_script_class_extends, const String &p_script_class_icon_path);
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
+19
-17
@@ -706,23 +706,7 @@ void EditorNode::_notification(int p_what) {
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
{
|
||||
started_timestamp = Time::get_singleton()->get_unix_time_from_system();
|
||||
_initializing_plugins = true;
|
||||
Vector<String> addons;
|
||||
if (ProjectSettings::get_singleton()->has_setting("editor_plugins/enabled")) {
|
||||
addons = GLOBAL_GET("editor_plugins/enabled");
|
||||
}
|
||||
|
||||
for (int i = 0; i < addons.size(); i++) {
|
||||
set_addon_plugin_enabled(addons[i], true);
|
||||
}
|
||||
_initializing_plugins = false;
|
||||
|
||||
if (!pending_addons.is_empty()) {
|
||||
EditorFileSystem::get_singleton()->connect("script_classes_updated", callable_mp(this, &EditorNode::_enable_pending_addons));
|
||||
}
|
||||
}
|
||||
started_timestamp = Time::get_singleton()->get_unix_time_from_system();
|
||||
|
||||
RenderingServer::get_singleton()->viewport_set_disable_2d(get_scene_root()->get_viewport_rid(), true);
|
||||
RenderingServer::get_singleton()->viewport_set_environment_mode(get_viewport()->get_viewport_rid(), RenderingServer::VIEWPORT_ENVIRONMENT_DISABLED);
|
||||
@@ -860,6 +844,23 @@ void EditorNode::_update_update_spinner() {
|
||||
OS::get_singleton()->set_low_processor_usage_mode(!update_continuously);
|
||||
}
|
||||
|
||||
void EditorNode::init_plugins() {
|
||||
_initializing_plugins = true;
|
||||
Vector<String> addons;
|
||||
if (ProjectSettings::get_singleton()->has_setting("editor_plugins/enabled")) {
|
||||
addons = GLOBAL_GET("editor_plugins/enabled");
|
||||
}
|
||||
|
||||
for (const String &addon : addons) {
|
||||
set_addon_plugin_enabled(addon, true);
|
||||
}
|
||||
_initializing_plugins = false;
|
||||
|
||||
if (!pending_addons.is_empty()) {
|
||||
EditorFileSystem::get_singleton()->connect("script_classes_updated", callable_mp(this, &EditorNode::_enable_pending_addons), CONNECT_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) {
|
||||
Ref<Script> scr = Object::cast_to<Script>(p_script);
|
||||
if (scr.is_null()) {
|
||||
@@ -954,6 +955,7 @@ void EditorNode::_fs_changed() {
|
||||
// FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed.
|
||||
String export_error;
|
||||
Error err = OK;
|
||||
// It's important to wait for the first scan to finish; otherwise, scripts or resources might not be imported.
|
||||
if (!export_defer.preset.is_empty() && !EditorFileSystem::get_singleton()->is_scanning()) {
|
||||
String preset_name = export_defer.preset;
|
||||
// Ensures export_project does not loop infinitely, because notifications may
|
||||
|
||||
@@ -683,6 +683,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Public for use with callable_mp.
|
||||
void init_plugins();
|
||||
void _on_plugin_ready(Object *p_script, const String &p_activate_name);
|
||||
|
||||
void editor_select(int p_which);
|
||||
|
||||
@@ -546,7 +546,7 @@ void FileSystemDock::_notification(int p_what) {
|
||||
|
||||
case NOTIFICATION_PROCESS: {
|
||||
if (EditorFileSystem::get_singleton()->is_scanning()) {
|
||||
scanning_progress->set_value(EditorFileSystem::get_singleton()->get_scanning_progress() * 100);
|
||||
scanning_progress->set_value(EditorFileSystem::get_singleton()->get_scanning_progress() * 100.0f);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
@@ -414,13 +414,19 @@ void EditorPlugin::remove_translation_parser_plugin(const Ref<EditorTranslationP
|
||||
void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer, bool p_first_priority) {
|
||||
ERR_FAIL_COND(!p_importer.is_valid());
|
||||
ResourceFormatImporter::get_singleton()->add_importer(p_importer, p_first_priority);
|
||||
callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::scan).call_deferred();
|
||||
// Plugins are now loaded during the first scan. It's important not to start another scan,
|
||||
// even a deferred one, as it would cause a scan during a scan at the next main thread iteration.
|
||||
if (!EditorFileSystem::get_singleton()->doing_first_scan()) {
|
||||
callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::scan).call_deferred();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importer) {
|
||||
ERR_FAIL_COND(!p_importer.is_valid());
|
||||
ResourceFormatImporter::get_singleton()->remove_importer(p_importer);
|
||||
if (!EditorNode::get_singleton()->is_exiting()) {
|
||||
// Plugins are now loaded during the first scan. It's important not to start another scan,
|
||||
// even a deferred one, as it would cause a scan during a scan at the next main thread iteration.
|
||||
if (!EditorNode::get_singleton()->is_exiting() && !EditorFileSystem::get_singleton()->doing_first_scan()) {
|
||||
callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::scan).call_deferred();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,10 @@ void ProjectSettingsEditor::update_plugins() {
|
||||
plugin_settings->update_plugins();
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::init_autoloads() {
|
||||
autoload_settings->init_autoloads();
|
||||
}
|
||||
|
||||
void ProjectSettingsEditor::_setting_edited(const String &p_name) {
|
||||
queue_save();
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ public:
|
||||
void set_plugins_page();
|
||||
void set_general_page(const String &p_category);
|
||||
void update_plugins();
|
||||
void init_autoloads();
|
||||
|
||||
EditorAutoloadSettings *get_autoload_settings() { return autoload_settings; }
|
||||
GroupSettingsEditor *get_group_settings() { return group_settings; }
|
||||
|
||||
@@ -2759,7 +2759,7 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
|
||||
String source = f->get_as_utf8_string();
|
||||
|
||||
GDScriptParser parser;
|
||||
err = parser.parse(source, p_path, false);
|
||||
err = parser.parse(source, p_path, false, false);
|
||||
|
||||
const GDScriptParser::ClassNode *c = parser.get_tree();
|
||||
if (!c) {
|
||||
|
||||
@@ -309,13 +309,14 @@ void GDScriptParser::set_last_completion_call_arg(int p_argument) {
|
||||
completion_call_stack.back()->get().argument = p_argument;
|
||||
}
|
||||
|
||||
Error GDScriptParser::parse(const String &p_source_code, const String &p_script_path, bool p_for_completion) {
|
||||
Error GDScriptParser::parse(const String &p_source_code, const String &p_script_path, bool p_for_completion, bool p_parse_body) {
|
||||
clear();
|
||||
|
||||
String source = p_source_code;
|
||||
int cursor_line = -1;
|
||||
int cursor_column = -1;
|
||||
for_completion = p_for_completion;
|
||||
parse_body = p_parse_body;
|
||||
|
||||
int tab_size = 4;
|
||||
#ifdef TOOLS_ENABLED
|
||||
@@ -689,6 +690,12 @@ void GDScriptParser::parse_program() {
|
||||
}
|
||||
}
|
||||
|
||||
// When the only thing needed is the class name and the icon, we don't need to parse the hole file.
|
||||
// It really speed up the call to GDScriptLanguage::get_global_class_name especially for large script.
|
||||
if (!parse_body) {
|
||||
return;
|
||||
}
|
||||
|
||||
#undef PUSH_PENDING_ANNOTATIONS_TO_HEAD
|
||||
|
||||
parse_class_body(true);
|
||||
|
||||
@@ -1329,6 +1329,7 @@ private:
|
||||
bool _is_tool = false;
|
||||
String script_path;
|
||||
bool for_completion = false;
|
||||
bool parse_body = true;
|
||||
bool panic_mode = false;
|
||||
bool can_break = false;
|
||||
bool can_continue = false;
|
||||
@@ -1560,7 +1561,7 @@ private:
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
public:
|
||||
Error parse(const String &p_source_code, const String &p_script_path, bool p_for_completion);
|
||||
Error parse(const String &p_source_code, const String &p_script_path, bool p_for_completion, bool p_parse_body = true);
|
||||
Error parse_binary(const Vector<uint8_t> &p_binary, const String &p_script_path);
|
||||
ClassNode *get_tree() const { return head; }
|
||||
bool is_tool() const { return _is_tool; }
|
||||
|
||||
Reference in New Issue
Block a user