uint64_t ClassDB::get_api_hash(APIType p_api) { OBJTYPE_RLOCK; #ifdef DEBUG_METHODS_ENABLED uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); List<StringName> names; const StringName *k = NULL; while ((k = classes.next(k))) { names.push_back(*k); } //must be alphabetically sorted for hash to compute names.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *E = names.front(); E; E = E->next()) { ClassInfo *t = classes.getptr(E->get()); ERR_FAIL_COND_V(!t, 0); if (t->api != p_api || !t->exposed) continue; hash = hash_djb2_one_64(t->name.hash(), hash); hash = hash_djb2_one_64(t->inherits.hash(), hash); { //methods List<StringName> snames; k = NULL; while ((k = t->method_map.next(k))) { snames.push_back(*k); } snames.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { MethodBind *mb = t->method_map[F->get()]; hash = hash_djb2_one_64(mb->get_name().hash(), hash); hash = hash_djb2_one_64(mb->get_argument_count(), hash); hash = hash_djb2_one_64(mb->get_argument_type(-1), hash); //return for (int i = 0; i < mb->get_argument_count(); i++) { const PropertyInfo info = mb->get_argument_info(i); hash = hash_djb2_one_64(info.type, hash); hash = hash_djb2_one_64(info.name.hash(), hash); hash = hash_djb2_one_64(info.hint, hash); hash = hash_djb2_one_64(info.hint_string.hash(), hash); } hash = hash_djb2_one_64(mb->get_default_argument_count(), hash); for (int i = 0; i < mb->get_default_argument_count(); i++) { //hash should not change, i hope for tis Variant da = mb->get_default_argument(i); hash = hash_djb2_one_64(da.hash(), hash); } hash = hash_djb2_one_64(mb->get_hint_flags(), hash); } } { //constants List<StringName> snames; k = NULL; while ((k = t->constant_map.next(k))) { snames.push_back(*k); } snames.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { hash = hash_djb2_one_64(F->get().hash(), hash); hash = hash_djb2_one_64(t->constant_map[F->get()], hash); } } { //signals List<StringName> snames; k = NULL; while ((k = t->signal_map.next(k))) { snames.push_back(*k); } snames.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { MethodInfo &mi = t->signal_map[F->get()]; hash = hash_djb2_one_64(F->get().hash(), hash); for (int i = 0; i < mi.arguments.size(); i++) { hash = hash_djb2_one_64(mi.arguments[i].type, hash); } } } { //properties List<StringName> snames; k = NULL; while ((k = t->property_setget.next(k))) { snames.push_back(*k); } snames.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { PropertySetGet *psg = t->property_setget.getptr(F->get()); hash = hash_djb2_one_64(F->get().hash(), hash); hash = hash_djb2_one_64(psg->setter.hash(), hash); hash = hash_djb2_one_64(psg->getter.hash(), hash); } } //property list for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { hash = hash_djb2_one_64(F->get().name.hash(), hash); hash = hash_djb2_one_64(F->get().type, hash); hash = hash_djb2_one_64(F->get().hint, hash); hash = hash_djb2_one_64(F->get().hint_string.hash(), hash); hash = hash_djb2_one_64(F->get().usage, hash); } } return hash; #else return 0; #endif }