diff options
| author | Rémi Verschelde <rverschelde@gmail.com> | 2024-02-09 12:34:36 +0100 |
|---|---|---|
| committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-02-09 12:34:36 +0100 |
| commit | 1774c17b64a0c0bf3f4f6ce85f38af576cf72a8a (patch) | |
| tree | a8a2e54e4ad17f03c034d716fdc7869dc54dc67a | |
| parent | dd275238d1d38df42949969e468b6889bbf21d9f (diff) | |
| parent | 9c919ea28504ae67226a5c8df94227e9da8899b7 (diff) | |
| download | redot-engine-1774c17b64a0c0bf3f4f6ce85f38af576cf72a8a.tar.gz | |
Merge pull request #87625 from YuriSizov/editor-lightweight-script-previews
Generate script resource preview without parsing
| -rw-r--r-- | core/object/script_language.cpp | 12 | ||||
| -rw-r--r-- | core/object/script_language.h | 1 | ||||
| -rw-r--r-- | editor/editor_resource_preview.cpp | 10 | ||||
| -rw-r--r-- | editor/plugins/editor_preview_plugins.cpp | 37 | ||||
| -rw-r--r-- | editor/plugins/editor_preview_plugins.h | 5 |
5 files changed, 55 insertions, 10 deletions
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 0b2d5e41cf..3b9b1f9094 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -168,6 +168,18 @@ ScriptLanguage *ScriptServer::get_language(int p_idx) { return _languages[p_idx]; } +ScriptLanguage *ScriptServer::get_language_for_extension(const String &p_extension) { + MutexLock lock(languages_mutex); + + for (int i = 0; i < _language_count; i++) { + if (_languages[i] && _languages[i]->get_extension() == p_extension) { + return _languages[i]; + } + } + + return nullptr; +} + Error ScriptServer::register_language(ScriptLanguage *p_language) { MutexLock lock(languages_mutex); ERR_FAIL_NULL_V(p_language, ERR_INVALID_PARAMETER); diff --git a/core/object/script_language.h b/core/object/script_language.h index bb714d5bc3..294231a3e7 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -75,6 +75,7 @@ public: static bool is_scripting_enabled(); _FORCE_INLINE_ static int get_language_count() { return _language_count; } static ScriptLanguage *get_language(int p_idx); + static ScriptLanguage *get_language_for_extension(const String &p_extension); static Error register_language(ScriptLanguage *p_language); static Error unregister_language(const ScriptLanguage *p_language); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 1702277ebc..623aa3f45c 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -129,6 +129,8 @@ void EditorResourcePreview::_preview_ready(const String &p_path, int p_hash, con void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base, Dictionary &p_metadata) { String type; + uint64_t started_at = OS::get_singleton()->get_ticks_usec(); + if (p_item.resource.is_valid()) { type = p_item.resource->get_class(); } else { @@ -138,6 +140,10 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< if (type.is_empty()) { r_texture = Ref<ImageTexture>(); r_small_texture = Ref<ImageTexture>(); + + if (is_print_verbose_enabled()) { + print_line(vformat("Generated '%s' preview in %d usec", p_item.path, OS::get_singleton()->get_ticks_usec() - started_at)); + } return; //could not guess type } @@ -196,6 +202,10 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref< _write_preview_cache(f, thumbnail_size, has_small_texture, FileAccess::get_modified_time(p_item.path), FileAccess::get_md5(p_item.path), p_metadata); } } + + if (is_print_verbose_enabled()) { + print_line(vformat("Generated '%s' preview in %d usec", p_item.path, OS::get_singleton()->get_ticks_usec() - started_at)); + } } const Dictionary EditorResourcePreview::get_preview_metadata(const String &p_path) const { diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 90bd117543..0019922f9c 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -464,6 +464,17 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Script"); } +Ref<Texture2D> EditorScriptPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size, Dictionary &p_metadata) const { + Error err; + String code = FileAccess::get_file_as_string(p_path, &err); + if (err != OK) { + return Ref<Texture2D>(); + } + + ScriptLanguage *lang = ScriptServer::get_language_for_extension(p_path.get_extension()); + return _generate_from_source_code(lang, code, p_size, p_metadata); +} + Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, const Size2 &p_size, Dictionary &p_metadata) const { Ref<Script> scr = p_from; if (scr.is_null()) { @@ -471,18 +482,24 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, } String code = scr->get_source_code().strip_edges(); - if (code.is_empty()) { + return _generate_from_source_code(scr->get_language(), code, p_size, p_metadata); +} + +Ref<Texture2D> EditorScriptPreviewPlugin::_generate_from_source_code(const ScriptLanguage *p_language, const String &p_source_code, const Size2 &p_size, Dictionary &p_metadata) const { + if (p_source_code.is_empty()) { return Ref<Texture2D>(); } List<String> kwors; - scr->get_language()->get_reserved_words(&kwors); + if (p_language) { + p_language->get_reserved_words(&kwors); + } HashSet<String> control_flow_keywords; HashSet<String> keywords; for (const String &E : kwors) { - if (scr->get_language()->is_control_flow_keyword(E)) { + if (p_language && p_language->is_control_flow_keyword(E)) { control_flow_keywords.insert(E); } else { keywords.insert(E); @@ -505,7 +522,7 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, if (bg_color.a == 0) { bg_color = Color(0, 0, 0, 0); } - bg_color.a = MAX(bg_color.a, 0.2); // some background + bg_color.a = MAX(bg_color.a, 0.2); // Ensure we have some background, regardless of the text editor setting. img->fill(bg_color); @@ -519,14 +536,14 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, bool in_keyword = false; bool in_comment = false; bool in_doc_comment = false; - for (int i = 0; i < code.length(); i++) { - char32_t c = code[i]; + for (int i = 0; i < p_source_code.length(); i++) { + char32_t c = p_source_code[i]; if (c > 32) { if (col < thumbnail_size) { Color color = text_color; if (c == '#') { - if (i < code.length() - 1 && code[i + 1] == '#') { + if (i < p_source_code.length() - 1 && p_source_code[i + 1] == '#') { in_doc_comment = true; } else { in_comment = true; @@ -539,17 +556,17 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const Ref<Resource> &p_from, color = doc_comment_color; } else { if (is_symbol(c)) { - //make symbol a little visible + // Make symbol a little visible. color = symbol_color; in_control_flow_keyword = false; in_keyword = false; } else if (!prev_is_text && is_ascii_identifier_char(c)) { int pos = i; - while (is_ascii_identifier_char(code[pos])) { + while (is_ascii_identifier_char(p_source_code[pos])) { pos++; } - String word = code.substr(i, pos - i); + String word = p_source_code.substr(i, pos - i); if (control_flow_keywords.has(word)) { in_control_flow_keyword = true; } else if (keywords.has(word)) { diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index f3786d8413..fa7015f423 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -34,6 +34,8 @@ #include "core/templates/safe_refcount.h" #include "editor/editor_resource_preview.h" +class ScriptLanguage; + void post_process_preview(Ref<Image> p_image); class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { @@ -112,9 +114,12 @@ public: class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { GDCLASS(EditorScriptPreviewPlugin, EditorResourcePreviewGenerator); + Ref<Texture2D> _generate_from_source_code(const ScriptLanguage *p_language, const String &p_source_code, const Size2 &p_size, Dictionary &p_metadata) const; + public: virtual bool handles(const String &p_type) const override; virtual Ref<Texture2D> generate(const Ref<Resource> &p_from, const Size2 &p_size, Dictionary &p_metadata) const override; + virtual Ref<Texture2D> generate_from_path(const String &p_path, const Size2 &p_size, Dictionary &p_metadata) const override; EditorScriptPreviewPlugin(); }; |
