You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
Improve reliability of editor docs cache
This commit is contained in:
@@ -53,6 +53,7 @@ MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint3
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClassDB::APIType ClassDB::current_api = API_CORE;
|
ClassDB::APIType ClassDB::current_api = API_CORE;
|
||||||
|
HashMap<ClassDB::APIType, uint64_t> ClassDB::api_hashes_cache;
|
||||||
|
|
||||||
void ClassDB::set_current_api(APIType p_api) {
|
void ClassDB::set_current_api(APIType p_api) {
|
||||||
current_api = p_api;
|
current_api = p_api;
|
||||||
@@ -165,6 +166,10 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
|
|||||||
OBJTYPE_RLOCK;
|
OBJTYPE_RLOCK;
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#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));
|
uint64_t hash = hash_murmur3_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG));
|
||||||
|
|
||||||
List<StringName> class_list;
|
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
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static APIType current_api;
|
static APIType current_api;
|
||||||
|
static HashMap<APIType, uint64_t> api_hashes_cache;
|
||||||
|
|
||||||
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
|
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
|
||||||
|
|
||||||
|
|||||||
@@ -374,6 +374,11 @@ void DocTools::generate(bool p_basic_types) {
|
|||||||
classes.pop_front();
|
classes.pop_front();
|
||||||
continue;
|
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;
|
String cname = name;
|
||||||
// Property setters and getters do not get exposed as individual methods.
|
// Property setters and getters do not get exposed as individual methods.
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
#include "core/input/input.h"
|
#include "core/input/input.h"
|
||||||
#include "core/os/keyboard.h"
|
#include "core/os/keyboard.h"
|
||||||
#include "core/version.h"
|
#include "core/version.h"
|
||||||
#include "core/version_generated.gen.h"
|
|
||||||
#include "doc_data_compressed.gen.h"
|
#include "doc_data_compressed.gen.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
@@ -2202,16 +2201,18 @@ String EditorHelp::get_cache_full_path() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool first_attempt = true;
|
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) {
|
void EditorHelp::_load_doc_thread(void *p_udata) {
|
||||||
DEV_ASSERT(first_attempt);
|
DEV_ASSERT(first_attempt);
|
||||||
Ref<DocCache> cache_res = ResourceLoader::load(get_cache_full_path());
|
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++) {
|
for (int i = 0; i < cache_res->get_classes().size(); i++) {
|
||||||
doc->add_doc(DocData::ClassDoc::from_dict(cache_res->get_classes()[i]));
|
doc->add_doc(DocData::ClassDoc::from_dict(cache_res->get_classes()[i]));
|
||||||
}
|
}
|
||||||
classes_whitelist.clear();
|
|
||||||
} else {
|
} else {
|
||||||
// We have to go back to the main thread to start from scratch.
|
// We have to go back to the main thread to start from scratch.
|
||||||
first_attempt = false;
|
first_attempt = false;
|
||||||
@@ -2226,7 +2227,7 @@ void EditorHelp::_gen_doc_thread(void *p_udata) {
|
|||||||
|
|
||||||
Ref<DocCache> cache_res;
|
Ref<DocCache> cache_res;
|
||||||
cache_res.instantiate();
|
cache_res.instantiate();
|
||||||
cache_res->set_version_hash(VERSION_HASH);
|
cache_res->set_version_hash(_compute_doc_version_hash());
|
||||||
Array classes;
|
Array classes;
|
||||||
for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) {
|
for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) {
|
||||||
classes.push_back(DocData::ClassDoc::to_dict(E.value));
|
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));
|
DEV_ASSERT(first_attempt == (doc == nullptr));
|
||||||
|
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
// Classes registered after this point should not have documentation generated.
|
|
||||||
ClassDB::get_class_list(&classes_whitelist);
|
|
||||||
|
|
||||||
GDREGISTER_CLASS(DocCache);
|
GDREGISTER_CLASS(DocCache);
|
||||||
doc = memnew(DocTools);
|
doc = memnew(DocTools);
|
||||||
}
|
}
|
||||||
@@ -2265,22 +2263,6 @@ void EditorHelp::generate_doc(bool p_use_cache) {
|
|||||||
} else {
|
} else {
|
||||||
print_verbose("Regenerating editor help cache");
|
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(¤t_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.
|
// Not doable on threads unfortunately, since it instantiates all sorts of classes to get default values.
|
||||||
doc->generate(true);
|
doc->generate(true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user