Move signal ownership from ClassDB to GDType.

This commit is contained in:
Lukas Tenbrink
2026-03-16 13:57:05 +01:00
parent a9afde8405
commit 7a73d3f16b
8 changed files with 51 additions and 58 deletions
+16 -47
View File
@@ -457,14 +457,14 @@ uint32_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames;
for (const KeyValue<StringName, MethodInfo> &F : t->signal_map) {
for (const KeyValue<StringName, const MethodInfo *> &F : t->gdtype->get_signal_map(true)) {
snames.push_back(F.key);
}
snames.sort_custom<StringName::AlphCompare>();
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<MethodInfo> *p_signals, bool p_no_inheritance) {
@@ -1294,52 +1284,31 @@ void ClassDB::get_signal_list(const StringName &p_class, List<MethodInfo> *p_sig
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL(type);
ClassInfo *check = type;
while (check) {
for (KeyValue<StringName, MethodInfo> &E : check->signal_map) {
p_signals->push_back(E.value);
}
if (p_no_inheritance) {
return;
}
check = check->inherits_ptr;
for (const KeyValue<StringName, const MethodInfo *> &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;
}
-1
View File
@@ -127,7 +127,6 @@ public:
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, LocalVector<MethodBind *>> method_map_compatibility;
AHashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list;
HashMap<StringName, PropertyInfo> property_map;
+19 -1
View File
@@ -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<StringName, const EnumInfo *> &kv : self_enum_map) {
memdelete(const_cast<EnumInfo *>(kv.value));
}
for (const KeyValue<StringName, const MethodInfo *> &kv : self_signal_map) {
memdelete(const_cast<MethodInfo *>(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;
}
+7
View File
@@ -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<StringName, const EnumInfo *> enum_map;
AHashMap<StringName, const EnumInfo *> self_enum_map;
AHashMap<StringName, const MethodInfo *> signal_map;
AHashMap<StringName, const MethodInfo *> self_signal_map;
public:
GDType(const GDType *p_super_type, StringName p_name);
~GDType();
@@ -82,4 +86,7 @@ public:
const AHashMap<StringName, int64_t> &get_integer_constant_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_constant_map : constant_map; }
const AHashMap<StringName, const EnumInfo *> &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<StringName, const MethodInfo *> &get_signal_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_signal_map : signal_map; }
};
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -146,7 +146,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
for (const KeyValue<StringName, MethodInfo> &F : t->signal_map) {
for (const KeyValue<StringName, const MethodInfo *> &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;
+3 -3
View File
@@ -4255,12 +4255,12 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
// Populate signals
const AHashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
const AHashMap<StringName, const MethodInfo *> &signal_map = class_info->gdtype->get_signal_map(true);
for (const KeyValue<StringName, MethodInfo> &E : signal_map) {
for (const KeyValue<StringName, const MethodInfo *> &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.
+3 -3
View File
@@ -711,12 +711,12 @@ void add_exposed_classes(Context &r_context) {
// Add signals
const AHashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
const AHashMap<StringName, const MethodInfo *> &signal_map = class_info->gdtype->get_signal_map(true);
for (const KeyValue<StringName, MethodInfo> &K : signal_map) {
for (const KeyValue<StringName, const MethodInfo *> &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(),