From fdecca2f18a7b2a9653afb07143767b3fa4bb11f Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Sun, 6 Apr 2025 19:55:34 +0200 Subject: [PATCH 1/2] Add `recording_signals` to MissingNode Allows connecting unknown signals to MissingNode so they aren't lost when the Node type is missing. --- doc/classes/MissingNode.xml | 3 +++ scene/main/missing_node.cpp | 23 +++++++++++++++++++++++ scene/main/missing_node.h | 8 ++++++++ 3 files changed, 34 insertions(+) diff --git a/doc/classes/MissingNode.xml b/doc/classes/MissingNode.xml index 9171c8321f2..d6d1ac0f01a 100644 --- a/doc/classes/MissingNode.xml +++ b/doc/classes/MissingNode.xml @@ -19,5 +19,8 @@ If [code]true[/code], allows new properties to be set along with existing ones. If [code]false[/code], only existing properties' values can be set, and new properties cannot be added. + + If [code]true[/code], allows new signals to be connected to along with existing ones. If [code]false[/code], only existing signals can be connected to, and new signals cannot be added. + diff --git a/scene/main/missing_node.cpp b/scene/main/missing_node.cpp index f071ea59a0a..10d426dd018 100644 --- a/scene/main/missing_node.cpp +++ b/scene/main/missing_node.cpp @@ -58,6 +58,17 @@ void MissingNode::_get_property_list(List *p_list) const { } } +#ifdef DEBUG_ENABLED +Error MissingNode::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) { + if (is_recording_signals()) { + if (!has_signal(p_signal)) { + add_user_signal(MethodInfo(p_signal)); + } + } + return Object::connect(p_signal, p_callable, p_flags); +} +#endif + void MissingNode::set_original_class(const String &p_class) { original_class = p_class; } @@ -82,6 +93,14 @@ bool MissingNode::is_recording_properties() const { return recording_properties; } +void MissingNode::set_recording_signals(bool p_enable) { + recording_signals = p_enable; +} + +bool MissingNode::is_recording_signals() const { + return recording_signals; +} + PackedStringArray MissingNode::get_configuration_warnings() const { // The mere existence of this node is warning. PackedStringArray warnings = Node::get_configuration_warnings(); @@ -107,10 +126,14 @@ void MissingNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_recording_properties", "enable"), &MissingNode::set_recording_properties); ClassDB::bind_method(D_METHOD("is_recording_properties"), &MissingNode::is_recording_properties); + ClassDB::bind_method(D_METHOD("set_recording_signals", "enable"), &MissingNode::set_recording_signals); + ClassDB::bind_method(D_METHOD("is_recording_signals"), &MissingNode::is_recording_signals); + // Expose, but not save. ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_class", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_original_class", "get_original_class"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "original_scene", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_original_scene", "get_original_scene"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recording_properties", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_recording_properties", "is_recording_properties"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recording_signals", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_recording_signals", "is_recording_signals"); } MissingNode::MissingNode() { diff --git a/scene/main/missing_node.h b/scene/main/missing_node.h index b986655e748..c8681b90f87 100644 --- a/scene/main/missing_node.h +++ b/scene/main/missing_node.h @@ -39,12 +39,17 @@ class MissingNode : public Node { String original_class; String original_scene; bool recording_properties = false; + bool recording_signals = false; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; +#ifdef DEBUG_ENABLED + virtual Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0) override; +#endif + static void _bind_methods(); public: @@ -57,6 +62,9 @@ public: void set_recording_properties(bool p_enable); bool is_recording_properties() const; + void set_recording_signals(bool p_enable); + bool is_recording_signals() const; + virtual PackedStringArray get_configuration_warnings() const override; MissingNode(); From 09ad9e535b98edf3a86f7f84662943d242abac44 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Thu, 9 Oct 2025 22:11:18 +0200 Subject: [PATCH 2/2] Rename `MTVIRTUAL` to `DEBUG_VIRTUAL` --- core/object/object.h | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/core/object/object.h b/core/object/object.h index de4ed485dc9..d39d228376b 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -926,22 +926,22 @@ public: /* SCRIPT */ -// When in debug, some non-virtual functions can be overridden for multithreaded guards. +// When in debug, some non-virtual functions can be overridden. #ifdef DEBUG_ENABLED -#define MTVIRTUAL virtual +#define DEBUG_VIRTUAL virtual #else -#define MTVIRTUAL +#define DEBUG_VIRTUAL #endif // DEBUG_ENABLED - MTVIRTUAL void set_script(const Variant &p_script); - MTVIRTUAL Variant get_script() const; + DEBUG_VIRTUAL void set_script(const Variant &p_script); + DEBUG_VIRTUAL Variant get_script() const; - MTVIRTUAL bool has_meta(const StringName &p_name) const; - MTVIRTUAL void set_meta(const StringName &p_name, const Variant &p_value); - MTVIRTUAL void remove_meta(const StringName &p_name); - MTVIRTUAL Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const; - MTVIRTUAL void get_meta_list(List *p_list) const; - MTVIRTUAL void merge_meta_from(const Object *p_src); + DEBUG_VIRTUAL bool has_meta(const StringName &p_name) const; + DEBUG_VIRTUAL void set_meta(const StringName &p_name, const Variant &p_value); + DEBUG_VIRTUAL void remove_meta(const StringName &p_name); + DEBUG_VIRTUAL Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const; + DEBUG_VIRTUAL void get_meta_list(List *p_list) const; + DEBUG_VIRTUAL void merge_meta_from(const Object *p_src); #ifdef TOOLS_ENABLED void set_edited(bool p_edited); @@ -968,18 +968,18 @@ public: return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); } - MTVIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount); - MTVIRTUAL bool has_signal(const StringName &p_name) const; - MTVIRTUAL void get_signal_list(List *p_signals) const; - MTVIRTUAL void get_signal_connection_list(const StringName &p_signal, List *p_connections) const; - MTVIRTUAL void get_all_signal_connections(List *p_connections) const; - MTVIRTUAL int get_persistent_signal_connection_count() const; - MTVIRTUAL void get_signals_connected_to_this(List *p_connections) const; + DEBUG_VIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount); + DEBUG_VIRTUAL bool has_signal(const StringName &p_name) const; + DEBUG_VIRTUAL void get_signal_list(List *p_signals) const; + DEBUG_VIRTUAL void get_signal_connection_list(const StringName &p_signal, List *p_connections) const; + DEBUG_VIRTUAL void get_all_signal_connections(List *p_connections) const; + DEBUG_VIRTUAL int get_persistent_signal_connection_count() const; + DEBUG_VIRTUAL void get_signals_connected_to_this(List *p_connections) const; - 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; + DEBUG_VIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0); + DEBUG_VIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable); + DEBUG_VIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const; + DEBUG_VIRTUAL bool has_connections(const StringName &p_signal) const; template void call_deferred(const StringName &p_name, VarArgs... p_args) {