diff options
author | A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> | 2024-01-18 17:20:56 +0100 |
---|---|---|
committer | A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> | 2024-09-20 16:39:09 +0200 |
commit | 203d3be200c9b607e5eaba82d9a267813a6700cd (patch) | |
tree | ced60a02eabb92aca3759a2f7165fb78352e852c | |
parent | 2be730a05b7ff221b89c967981f7caee6e164ef0 (diff) | |
download | redot-engine-203d3be200c9b607e5eaba82d9a267813a6700cd.tar.gz |
[Core] Add way to check if a signal has any connections
Added to `Object` and `Signal`
-rw-r--r-- | core/object/object.cpp | 19 | ||||
-rw-r--r-- | core/object/object.h | 1 | ||||
-rw-r--r-- | core/variant/callable.cpp | 7 | ||||
-rw-r--r-- | core/variant/callable.h | 1 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 1 | ||||
-rw-r--r-- | doc/classes/Object.xml | 8 | ||||
-rw-r--r-- | doc/classes/Signal.xml | 6 | ||||
-rw-r--r-- | scene/main/node.cpp | 5 | ||||
-rw-r--r-- | scene/main/node.h | 1 |
9 files changed, 49 insertions, 0 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp index 2d9d468d38..b3a4ec6e2e 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1457,6 +1457,24 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable return s->slot_map.has(*p_callable.get_base_comparator()); } +bool Object::has_connections(const StringName &p_signal) const { + const SignalData *s = signal_map.getptr(p_signal); + if (!s) { + bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal); + if (signal_is_valid) { + return false; + } + + if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)) { + return false; + } + + ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + "."); + } + + return !s->slot_map.is_empty(); +} + void Object::disconnect(const StringName &p_signal, const Callable &p_callable) { _disconnect(p_signal, p_callable); } @@ -1697,6 +1715,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "flags"), &Object::connect, DEFVAL(0)); ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect); ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected); + ClassDB::bind_method(D_METHOD("has_connections", "signal"), &Object::has_connections); ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals); ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals); diff --git a/core/object/object.h b/core/object/object.h index 1274247d71..763e2974b9 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -932,6 +932,7 @@ public: MTVIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0); MTVIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable); MTVIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const; + MTVIRTUAL bool has_connections(const StringName &p_signal) const; template <typename... VarArgs> void call_deferred(const StringName &p_name, VarArgs... p_args) { diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 9dff5c1e91..bb2d0313f6 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -545,6 +545,13 @@ bool Signal::is_connected(const Callable &p_callable) const { return obj->is_connected(name, p_callable); } +bool Signal::has_connections() const { + Object *obj = get_object(); + ERR_FAIL_NULL_V(obj, false); + + return obj->has_connections(name); +} + Array Signal::get_connections() const { Object *obj = get_object(); if (!obj) { diff --git a/core/variant/callable.h b/core/variant/callable.h index 63757d9d6e..e3c940a0e5 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -192,6 +192,7 @@ public: Error connect(const Callable &p_callable, uint32_t p_flags = 0); void disconnect(const Callable &p_callable); bool is_connected(const Callable &p_callable) const; + bool has_connections() const; Array get_connections() const; Signal(const Object *p_object, const StringName &p_name); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 178c0bc4ec..63fb5e8d94 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -2121,6 +2121,7 @@ static void _register_variant_builtin_methods_misc() { bind_method(Signal, disconnect, sarray("callable"), varray()); bind_method(Signal, is_connected, sarray("callable"), varray()); bind_method(Signal, get_connections, sarray(), varray()); + bind_method(Signal, has_connections, sarray(), varray()); bind_custom(Signal, emit, _VariantCall::func_Signal_emit, false, Variant); diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index d0d0876108..2767a11e80 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -824,6 +824,14 @@ Returns the name of the translation domain used by [method tr] and [method tr_n]. See also [TranslationServer]. </description> </method> + <method name="has_connections" qualifiers="const"> + <return type="bool" /> + <param index="0" name="signal" type="StringName" /> + <description> + Returns [code]true[/code] if any connection exists on the given [param signal] name. + [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot methods. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call. + </description> + </method> <method name="has_meta" qualifiers="const"> <return type="bool" /> <param index="0" name="name" type="StringName" /> diff --git a/doc/classes/Signal.xml b/doc/classes/Signal.xml index 7d6ff1e9b0..65168d6980 100644 --- a/doc/classes/Signal.xml +++ b/doc/classes/Signal.xml @@ -109,6 +109,12 @@ Returns the ID of the object emitting this signal (see [method Object.get_instance_id]). </description> </method> + <method name="has_connections" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if any [Callable] is connected to this signal. + </description> + </method> <method name="is_connected" qualifiers="const"> <return type="bool" /> <param index="0" name="callable" type="Callable" /> diff --git a/scene/main/node.cpp b/scene/main/node.cpp index eb3448e1a2..d921cc5b67 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -4019,4 +4019,9 @@ bool Node::is_connected(const StringName &p_signal, const Callable &p_callable) return Object::is_connected(p_signal, p_callable); } +bool Node::has_connections(const StringName &p_signal) const { + ERR_THREAD_GUARD_V(false); + return Object::has_connections(p_signal); +} + #endif diff --git a/scene/main/node.h b/scene/main/node.h index 4560ed085c..298cbc7e59 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -797,6 +797,7 @@ public: virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0) override; virtual void disconnect(const StringName &p_signal, const Callable &p_callable) override; virtual bool is_connected(const StringName &p_signal, const Callable &p_callable) const override; + virtual bool has_connections(const StringName &p_signal) const override; #endif Node(); ~Node(); |