diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index e912a8f8bc..2f8a910f5e 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -457,14 +457,14 @@ uint32_t ClassDB::get_api_hash(APIType p_api) { List snames; - for (const KeyValue &F : t->signal_map) { + for (const KeyValue &F : t->gdtype->get_signal_map(true)) { snames.push_back(F.key); } snames.sort_custom(); for (const StringName &F : snames) { - MethodInfo &mi = t->signal_map[F]; + const MethodInfo &mi = *t->gdtype->get_signal_map(true)[F]; hash = hash_murmur3_one_64(F.hash(), hash); for (const PropertyInfo &pi : mi.arguments) { hash = hash_murmur3_one_64(pi.type, hash); @@ -1275,17 +1275,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); - StringName sname = p_signal.name; - -#ifdef DEBUG_ENABLED - ClassInfo *check = type; - while (check) { - ERR_FAIL_COND_MSG(check->signal_map.has(sname), vformat("Class '%s' already has signal '%s'.", String(p_class), String(sname))); - check = check->inherits_ptr; - } -#endif // DEBUG_ENABLED - - type->signal_map[sname] = p_signal; + type->gdtype->add_signal(p_signal); } void ClassDB::get_signal_list(const StringName &p_class, List *p_signals, bool p_no_inheritance) { @@ -1294,52 +1284,31 @@ void ClassDB::get_signal_list(const StringName &p_class, List *p_sig ClassInfo *type = classes.getptr(p_class); ERR_FAIL_NULL(type); - ClassInfo *check = type; - - while (check) { - for (KeyValue &E : check->signal_map) { - p_signals->push_back(E.value); - } - - if (p_no_inheritance) { - return; - } - - check = check->inherits_ptr; + for (const KeyValue &kv : type->gdtype->get_signal_map(p_no_inheritance)) { + p_signals->push_back(*kv.value); } } bool ClassDB::has_signal(const StringName &p_class, const StringName &p_signal, bool p_no_inheritance) { Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); - ClassInfo *check = type; - while (check) { - if (check->signal_map.has(p_signal)) { - return true; - } - if (p_no_inheritance) { - return false; - } - check = check->inherits_ptr; + if (!type) { + return false; } - - return false; + return type->gdtype->get_signal_map(p_no_inheritance).has(p_signal); } bool ClassDB::get_signal(const StringName &p_class, const StringName &p_signal, MethodInfo *r_signal) { Locker::Lock lock(Locker::STATE_READ); ClassInfo *type = classes.getptr(p_class); - ClassInfo *check = type; - while (check) { - if (check->signal_map.has(p_signal)) { - if (r_signal) { - *r_signal = check->signal_map[p_signal]; - } - return true; - } - check = check->inherits_ptr; + if (!type) { + return false; + } + const MethodInfo *const *method_info = type->gdtype->get_signal_map(false).getptr(p_signal); + if (method_info) { + *r_signal = **method_info; + return true; } - return false; } @@ -1619,7 +1588,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia return true; } - if (check->signal_map.has(p_property)) { //signals count + if (check->gdtype->get_signal_map(true).has(p_property)) { //signals count r_value = Signal(p_object, p_property); return true; } diff --git a/core/object/class_db.h b/core/object/class_db.h index edd5cb47fd..8e72e6a317 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -127,7 +127,6 @@ public: HashMap method_map; HashMap> method_map_compatibility; - AHashMap signal_map; List property_list; HashMap property_map; diff --git a/core/object/gdtype.cpp b/core/object/gdtype.cpp index b6466674e5..6511fcd492 100644 --- a/core/object/gdtype.cpp +++ b/core/object/gdtype.cpp @@ -30,6 +30,7 @@ #include "gdtype.h" +#include "core/os/memory.h" #include "core/os/thread.h" GDType::GDType(const GDType *p_super_type, StringName p_name) : @@ -47,6 +48,9 @@ GDType::~GDType() { for (const KeyValue &kv : self_enum_map) { memdelete(const_cast(kv.value)); } + for (const KeyValue &kv : self_signal_map) { + memdelete(const_cast(kv.value)); + } } void GDType::initialize() { @@ -61,6 +65,7 @@ void GDType::initialize() { constant_map = super_type->constant_map; enum_map = super_type->enum_map; + signal_map = super_type->signal_map; } init_state = InitState::MUTABLE; @@ -69,7 +74,7 @@ void GDType::initialize() { void GDType::bind_integer_constant(const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) { ERR_FAIL_COND(!Thread::is_main_thread()); ERR_FAIL_COND(init_state != InitState::MUTABLE); - ERR_FAIL_COND(self_constant_map.has(p_name)); + ERR_FAIL_COND_MSG(self_constant_map.has(p_name), vformat("Class '%s' already has constant '%s'.", String(name), String(p_name))); constant_map[p_name] = p_constant; self_constant_map[p_name] = p_constant; @@ -106,3 +111,16 @@ const GDType::EnumInfo *GDType::get_integer_constant_enum(const StringName &p_na return nullptr; } + +void GDType::add_signal(MethodInfo p_signal) { + ERR_FAIL_COND(!Thread::is_main_thread()); + ERR_FAIL_COND(init_state != InitState::MUTABLE); + + const StringName signal_name(p_signal.name); + ERR_FAIL_COND_MSG(signal_map.has(signal_name), vformat("Class '%s' already has signal '%s'.", String(name), String(signal_name))); + + const MethodInfo *ptr = memnew(MethodInfo(std::move(p_signal))); + + signal_map[signal_name] = ptr; + self_signal_map[std::move(signal_name)] = ptr; +} diff --git a/core/object/gdtype.h b/core/object/gdtype.h index 6ee8f17459..2080142a18 100644 --- a/core/object/gdtype.h +++ b/core/object/gdtype.h @@ -30,6 +30,7 @@ #pragma once +#include "core/object/method_info.h" #include "core/string/string_name.h" #include "core/templates/a_hash_map.h" #include "core/templates/vector.h" @@ -63,6 +64,9 @@ protected: AHashMap enum_map; AHashMap self_enum_map; + AHashMap signal_map; + AHashMap self_signal_map; + public: GDType(const GDType *p_super_type, StringName p_name); ~GDType(); @@ -82,4 +86,7 @@ public: const AHashMap &get_integer_constant_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_constant_map : constant_map; } const AHashMap &get_enum_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_enum_map : enum_map; } const EnumInfo *get_integer_constant_enum(const StringName &p_name, bool p_no_inheritance = false) const; + + void add_signal(MethodInfo p_signal); + const AHashMap &get_signal_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_signal_map : signal_map; } }; diff --git a/core/object/object.h b/core/object/object.h index 0091391ef2..c6de0e595f 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -43,7 +43,7 @@ #include "core/templates/safe_refcount.h" #include "core/variant/variant.h" -#define ADD_SIGNAL(m_signal) ::ClassDB::add_signal(get_class_static(), m_signal) +#define ADD_SIGNAL(m_signal) get_gdtype_static_mutable().add_signal(m_signal) #define ADD_PROPERTY(m_property, m_setter, m_getter) ::ClassDB::add_property(get_class_static(), m_property, StringName(m_setter), StringName(m_getter)) #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, StringName(m_setter), StringName(m_getter), m_index) #define ADD_PROPERTY_DEFAULT(m_property, m_default) ::ClassDB::set_property_default_value(get_class_static(), m_property, m_default) diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp index b0acf6659e..d9b84f0cee 100644 --- a/modules/mono/class_db_api_json.cpp +++ b/modules/mono/class_db_api_json.cpp @@ -146,7 +146,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { List snames; - for (const KeyValue &F : t->signal_map) { + for (const KeyValue &F : t->gdtype->get_signal_map(true)) { snames.push_back(F.key); } @@ -158,7 +158,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { Dictionary signal_dict; signals.push_back(signal_dict); - MethodInfo &mi = t->signal_map[F]; + const MethodInfo &mi = *t->gdtype->get_signal_map(true)[F]; signal_dict["name"] = F; Array arguments; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 884eb53fa3..666ee8b22a 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -4255,12 +4255,12 @@ bool BindingsGenerator::_populate_object_type_interfaces() { // Populate signals - const AHashMap &signal_map = class_info->signal_map; + const AHashMap &signal_map = class_info->gdtype->get_signal_map(true); - for (const KeyValue &E : signal_map) { + for (const KeyValue &E : signal_map) { SignalInterface isignal; - const MethodInfo &method_info = E.value; + const MethodInfo &method_info = *E.value; if (method_info.name.begins_with("_")) { // Signals starting with an underscore are internal and not meant to be exposed. diff --git a/tests/core/object/test_class_db.cpp b/tests/core/object/test_class_db.cpp index 2b76050134..28c8405f70 100644 --- a/tests/core/object/test_class_db.cpp +++ b/tests/core/object/test_class_db.cpp @@ -711,12 +711,12 @@ void add_exposed_classes(Context &r_context) { // Add signals - const AHashMap &signal_map = class_info->signal_map; + const AHashMap &signal_map = class_info->gdtype->get_signal_map(true); - for (const KeyValue &K : signal_map) { + for (const KeyValue &K : signal_map) { SignalData signal; - const MethodInfo &method_info = signal_map.get(K.key); + const MethodInfo &method_info = *signal_map.get(K.key); signal.name = method_info.name; TEST_FAIL_COND(!String(signal.name).is_valid_ascii_identifier(),