diff options
-rw-r--r-- | core/object/object.cpp | 19 | ||||
-rw-r--r-- | core/object/object.h | 2 | ||||
-rw-r--r-- | doc/classes/Object.xml | 11 |
3 files changed, 30 insertions, 2 deletions
diff --git a/core/object/object.cpp b/core/object/object.cpp index 06f6e8e9e6..f8d2feb5a8 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1100,6 +1100,20 @@ bool Object::_has_user_signal(const StringName &p_name) const { return signal_map[p_name].user.name.length() > 0; } +void Object::_remove_user_signal(const StringName &p_name) { + SignalData *s = signal_map.getptr(p_name); + ERR_FAIL_NULL_MSG(s, "Provided signal does not exist."); + ERR_FAIL_COND_MSG(!s->removable, "Signal is not removable (not added with add_user_signal)."); + for (const KeyValue<Callable, SignalData::Slot> &slot_kv : s->slot_map) { + Object *target = slot_kv.key.get_object(); + if (likely(target)) { + target->connections.erase(slot_kv.value.cE); + } + } + + signal_map.erase(p_name); +} + Error Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (unlikely(p_argcount < 1)) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; @@ -1248,6 +1262,10 @@ void Object::_add_user_signal(const String &p_name, const Array &p_args) { } add_user_signal(mi); + + if (signal_map.has(p_name)) { + signal_map.getptr(p_name)->removable = true; + } } TypedArray<Dictionary> Object::_get_signal_list() const { @@ -1661,6 +1679,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("add_user_signal", "signal", "arguments"), &Object::_add_user_signal, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("has_user_signal", "signal"), &Object::_has_user_signal); + ClassDB::bind_method(D_METHOD("remove_user_signal", "signal"), &Object::_remove_user_signal); { MethodInfo mi; diff --git a/core/object/object.h b/core/object/object.h index d9551ecd01..915c3a8c25 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -619,6 +619,7 @@ private: MethodInfo user; HashMap<Callable, Slot, HashableHasher<Callable>> slot_map; + bool removable = false; }; HashMap<StringName, SignalData> signal_map; @@ -646,6 +647,7 @@ private: void _add_user_signal(const String &p_name, const Array &p_args = Array()); bool _has_user_signal(const StringName &p_name) const; + void _remove_user_signal(const StringName &p_name); Error _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error); TypedArray<Dictionary> _get_signal_list() const; TypedArray<Dictionary> _get_signal_connection_list(const StringName &p_signal) const; diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index c508591093..961cb2e684 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -357,7 +357,7 @@ <param index="0" name="signal" type="String" /> <param index="1" name="arguments" type="Array" default="[]" /> <description> - Adds a user-defined [param signal]. Optional arguments for the signal can be added as an [Array] of dictionaries, each defining a [code]name[/code] [String] and a [code]type[/code] [int] (see [enum Variant.Type]). See also [method has_user_signal]. + Adds a user-defined [param signal]. Optional arguments for the signal can be added as an [Array] of dictionaries, each defining a [code]name[/code] [String] and a [code]type[/code] [int] (see [enum Variant.Type]). See also [method has_user_signal] and [method remove_user_signal]. [codeblocks] [gdscript] add_user_signal("hurt", [ @@ -797,7 +797,7 @@ <return type="bool" /> <param index="0" name="signal" type="StringName" /> <description> - Returns [code]true[/code] if the given user-defined [param signal] name exists. Only signals added with [method add_user_signal] are included. + Returns [code]true[/code] if the given user-defined [param signal] name exists. Only signals added with [method add_user_signal] are included. See also [method remove_user_signal]. </description> </method> <method name="is_blocking_signals" qualifiers="const"> @@ -905,6 +905,13 @@ [b]Note:[/b] Metadata that has a name starting with an underscore ([code]_[/code]) is considered editor-only. Editor-only metadata is not displayed in the Inspector and should not be edited, although it can still be found by this method. </description> </method> + <method name="remove_user_signal" experimental=""> + <return type="void" /> + <param index="0" name="signal" type="StringName" /> + <description> + Removes the given user signal [param signal] from the object. See also [method add_user_signal] and [method has_user_signal]. + </description> + </method> <method name="set"> <return type="void" /> <param index="0" name="property" type="StringName" /> |