From e1ce0340b78875a864d449a5e3e38e4535e9a800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 25 Apr 2023 11:40:56 +0200 Subject: [PATCH] Improve reliability of editor docs cache --- core/object/class_db.cpp | 9 ++++++++- core/object/class_db.h | 1 + editor/doc_tools.cpp | 5 +++++ editor/editor_help.cpp | 30 ++++++------------------------ 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index a602dc9fb837..d920ae6ca05b 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -53,6 +53,7 @@ MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint3 #endif ClassDB::APIType ClassDB::current_api = API_CORE; +HashMap ClassDB::api_hashes_cache; void ClassDB::set_current_api(APIType p_api) { current_api = p_api; @@ -165,6 +166,10 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { OBJTYPE_RLOCK; #ifdef DEBUG_METHODS_ENABLED + if (api_hashes_cache.has(p_api)) { + return api_hashes_cache[p_api]; + } + uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); List class_list; @@ -290,7 +295,9 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { } } - return hash_fmix32(hash); + hash = hash_fmix32(hash); + api_hashes_cache[p_api] = hash; + return hash; #else return 0; #endif diff --git a/core/object/class_db.h b/core/object/class_db.h index 0b62cf40f746..1a5e9235cf19 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -154,6 +154,7 @@ public: #endif static APIType current_api; + static HashMap api_hashes_cache; static void _add_class2(const StringName &p_class, const StringName &p_inherits); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 110fa941afa7..996e16be337c 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -374,6 +374,11 @@ void DocTools::generate(bool p_basic_types) { classes.pop_front(); continue; } + if (ClassDB::get_api_type(name) != ClassDB::API_CORE && ClassDB::get_api_type(name) != ClassDB::API_EDITOR) { + print_verbose(vformat("Class '%s' belongs neither to core nor editor, skipping.", name)); + classes.pop_front(); + continue; + } String cname = name; // Property setters and getters do not get exposed as individual methods. diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index c2801e118878..b9634a7e03c9 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -34,7 +34,6 @@ #include "core/input/input.h" #include "core/os/keyboard.h" #include "core/version.h" -#include "core/version_generated.gen.h" #include "doc_data_compressed.gen.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" @@ -2202,16 +2201,18 @@ String EditorHelp::get_cache_full_path() { } static bool first_attempt = true; -static List classes_whitelist; + +static String _compute_doc_version_hash() { + return uitos(ClassDB::get_api_hash(ClassDB::API_CORE)) + "-" + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)); +} void EditorHelp::_load_doc_thread(void *p_udata) { DEV_ASSERT(first_attempt); Ref cache_res = ResourceLoader::load(get_cache_full_path()); - if (cache_res.is_valid() && cache_res->get_version_hash() == String(VERSION_HASH)) { + if (cache_res.is_valid() && cache_res->get_version_hash() == _compute_doc_version_hash()) { for (int i = 0; i < cache_res->get_classes().size(); i++) { doc->add_doc(DocData::ClassDoc::from_dict(cache_res->get_classes()[i])); } - classes_whitelist.clear(); } else { // We have to go back to the main thread to start from scratch. first_attempt = false; @@ -2226,7 +2227,7 @@ void EditorHelp::_gen_doc_thread(void *p_udata) { Ref cache_res; cache_res.instantiate(); - cache_res->set_version_hash(VERSION_HASH); + cache_res->set_version_hash(_compute_doc_version_hash()); Array classes; for (const KeyValue &E : doc->class_list) { classes.push_back(DocData::ClassDoc::to_dict(E.value)); @@ -2249,9 +2250,6 @@ void EditorHelp::generate_doc(bool p_use_cache) { DEV_ASSERT(first_attempt == (doc == nullptr)); if (!doc) { - // Classes registered after this point should not have documentation generated. - ClassDB::get_class_list(&classes_whitelist); - GDREGISTER_CLASS(DocCache); doc = memnew(DocTools); } @@ -2265,22 +2263,6 @@ void EditorHelp::generate_doc(bool p_use_cache) { } else { print_verbose("Regenerating editor help cache"); - if (!first_attempt) { - // Some classes that should not be exposed may have been registered by now. Unexpose them. - // Arduous, but happens only when regenerating. - List current_classes; - ClassDB::get_class_list(¤t_classes); - List::Element *W = classes_whitelist.front(); - for (const StringName &name : current_classes) { - if (W && W->get() == name) { - W = W->next(); - } else { - ClassDB::classes[name].exposed = false; - } - } - } - classes_whitelist.clear(); - // Not doable on threads unfortunately, since it instantiates all sorts of classes to get default values. doc->generate(true);