Browse Source

Improve reliability of editor docs cache

Pedro J. Estébanez 2 years ago
parent
commit
e1ce0340b7
4 changed files with 20 additions and 25 deletions
  1. 8 1
      core/object/class_db.cpp
  2. 1 0
      core/object/class_db.h
  3. 5 0
      editor/doc_tools.cpp
  4. 6 24
      editor/editor_help.cpp

+ 8 - 1
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::APIType, uint64_t> 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<StringName> 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

+ 1 - 0
core/object/class_db.h

@@ -154,6 +154,7 @@ public:
 #endif
 
 	static APIType current_api;
+	static HashMap<APIType, uint64_t> api_hashes_cache;
 
 	static void _add_class2(const StringName &p_class, const StringName &p_inherits);
 

+ 5 - 0
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.

+ 6 - 24
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<StringName> 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<DocCache> 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<DocCache> 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<String, DocData::ClassDoc> &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<StringName> current_classes;
-			ClassDB::get_class_list(&current_classes);
-			List<StringName>::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);