Explorar el Código

Reworked signal connection system, added support for Callable and Signal objects and made them default.

Juan Linietsky hace 5 años
padre
commit
69c95f4b4c
Se han modificado 100 ficheros con 2139 adiciones y 1258 borrados
  1. 2 2
      core/array.cpp
  2. 6 6
      core/bind/core_bind.cpp
  3. 357 0
      core/callable.cpp
  4. 162 0
      core/callable.h
  5. 15 5
      core/class_db.cpp
  6. 5 1
      core/core_string_names.cpp
  7. 5 0
      core/core_string_names.h
  8. 3 3
      core/func_ref.cpp
  9. 1 1
      core/func_ref.h
  10. 2 0
      core/global_constants.cpp
  11. 2 2
      core/io/dtls_server.cpp
  12. 2 2
      core/io/dtls_server.h
  13. 15 0
      core/io/marshalls.cpp
  14. 17 17
      core/io/multiplayer_api.cpp
  15. 2 2
      core/io/packet_peer_dtls.cpp
  16. 2 2
      core/io/packet_peer_dtls.h
  17. 22 0
      core/io/resource_format_binary.cpp
  18. 2 2
      core/io/udp_server.cpp
  19. 2 2
      core/io/udp_server.h
  20. 12 12
      core/make_binders.py
  21. 27 27
      core/math/expression.cpp
  22. 1 1
      core/math/expression.h
  23. 54 51
      core/message_queue.cpp
  24. 3 3
      core/message_queue.h
  25. 5 5
      core/method_bind.h
  26. 2 0
      core/method_ptrcall.h
  27. 114 130
      core/object.cpp
  28. 19 32
      core/object.h
  29. 30 0
      core/object_id.h
  30. 3 0
      core/register_core_types.cpp
  31. 3 3
      core/script_language.cpp
  32. 4 4
      core/script_language.h
  33. 2 0
      core/type_info.h
  34. 12 12
      core/undo_redo.cpp
  35. 2 2
      core/undo_redo.h
  36. 133 16
      core/variant.cpp
  37. 13 19
      core/variant.h
  38. 124 23
      core/variant_call.cpp
  39. 78 35
      core/variant_op.cpp
  40. 10 10
      editor/animation_bezier_editor.cpp
  41. 62 62
      editor/animation_track_editor.cpp
  42. 2 2
      editor/animation_track_editor_plugins.cpp
  43. 3 3
      editor/array_property_edit.cpp
  44. 27 27
      editor/code_editor.cpp
  45. 37 30
      editor/connections_dialog.cpp
  46. 33 3
      editor/connections_dialog.h
  47. 12 12
      editor/create_dialog.cpp
  48. 8 8
      editor/dependency_editor.cpp
  49. 7 6
      editor/doc/doc_data.cpp
  50. 1 1
      editor/editor_about.cpp
  51. 1 1
      editor/editor_asset_installer.cpp
  52. 28 28
      editor/editor_audio_buses.cpp
  53. 9 9
      editor/editor_autoload_settings.cpp
  54. 2 2
      editor/editor_data.cpp
  55. 10 10
      editor/editor_dir_dialog.cpp
  56. 1 1
      editor/editor_export.cpp
  57. 15 15
      editor/editor_feature_profile.cpp
  58. 31 31
      editor/editor_file_dialog.cpp
  59. 9 9
      editor/editor_help.cpp
  60. 8 8
      editor/editor_help_search.cpp
  61. 25 25
      editor/editor_inspector.cpp
  62. 2 2
      editor/editor_layouts_dialog.cpp
  63. 2 2
      editor/editor_log.cpp
  64. 3 3
      editor/editor_network_profiler.cpp
  65. 82 82
      editor/editor_node.cpp
  66. 2 2
      editor/editor_path.cpp
  67. 5 5
      editor/editor_plugin_settings.cpp
  68. 11 11
      editor/editor_profiler.cpp
  69. 57 57
      editor/editor_properties.cpp
  70. 22 22
      editor/editor_properties_array_dict.cpp
  71. 2 2
      editor/editor_run_native.cpp
  72. 3 3
      editor/editor_run_script.cpp
  73. 2 2
      editor/editor_sectioned_inspector.cpp
  74. 6 6
      editor/editor_spin_slider.cpp
  75. 6 6
      editor/editor_sub_scene.cpp
  76. 12 12
      editor/editor_visual_profiler.cpp
  77. 10 10
      editor/export_template_manager.cpp
  78. 33 33
      editor/filesystem_dock.cpp
  79. 12 12
      editor/find_in_files.cpp
  80. 16 16
      editor/groups_editor.cpp
  81. 5 5
      editor/import_dock.cpp
  82. 13 13
      editor/inspector_dock.cpp
  83. 2 2
      editor/node_dock.cpp
  84. 4 4
      editor/plugin_config_dialog.cpp
  85. 5 5
      editor/plugins/abstract_polygon_2d_editor.cpp
  86. 16 16
      editor/plugins/animation_blend_space_1d_editor.cpp
  87. 26 26
      editor/plugins/animation_blend_space_2d_editor.cpp
  88. 21 21
      editor/plugins/animation_blend_tree_editor_plugin.cpp
  89. 27 27
      editor/plugins/animation_player_editor_plugin.cpp
  90. 16 16
      editor/plugins/animation_state_machine_editor.cpp
  91. 2 2
      editor/plugins/animation_tree_editor_plugin.cpp
  92. 32 32
      editor/plugins/asset_library_editor_plugin.cpp
  93. 7 7
      editor/plugins/audio_stream_editor_plugin.cpp
  94. 1 1
      editor/plugins/camera_editor_plugin.cpp
  95. 53 53
      editor/plugins/canvas_item_editor_plugin.cpp
  96. 3 3
      editor/plugins/collision_polygon_editor_plugin.cpp
  97. 3 3
      editor/plugins/cpu_particles_2d_editor_plugin.cpp
  98. 1 1
      editor/plugins/cpu_particles_editor_plugin.cpp
  99. 6 6
      editor/plugins/curve_editor_plugin.cpp
  100. 2 2
      editor/plugins/gi_probe_editor_plugin.cpp

+ 2 - 2
core/array.cpp

@@ -308,9 +308,9 @@ struct _ArrayVariantSortCustom {
 	_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
 
 		const Variant *args[2] = { &p_l, &p_r };
-		Variant::CallError err;
+		Callable::CallError err;
 		bool res = obj->call(func, args, 2, err);
-		if (err.error != Variant::CallError::CALL_OK)
+		if (err.error != Callable::CallError::CALL_OK)
 			res = false;
 		return res;
 	}

+ 6 - 6
core/bind/core_bind.cpp

@@ -2620,29 +2620,29 @@ void _Thread::_start_func(void *ud) {
 	Ref<_Thread> *tud = (Ref<_Thread> *)ud;
 	Ref<_Thread> t = *tud;
 	memdelete(tud);
-	Variant::CallError ce;
+	Callable::CallError ce;
 	const Variant *arg[1] = { &t->userdata };
 
 	Thread::set_name(t->target_method);
 
 	t->ret = t->target_instance->call(t->target_method, arg, 1, ce);
-	if (ce.error != Variant::CallError::CALL_OK) {
+	if (ce.error != Callable::CallError::CALL_OK) {
 
 		String reason;
 		switch (ce.error) {
-			case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+			case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
 
 				reason = "Invalid Argument #" + itos(ce.argument);
 			} break;
-			case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+			case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
 
 				reason = "Too Many Arguments";
 			} break;
-			case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+			case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
 
 				reason = "Too Few Arguments";
 			} break;
-			case Variant::CallError::CALL_ERROR_INVALID_METHOD: {
+			case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
 
 				reason = "Method Not Found";
 			} break;

+ 357 - 0
core/callable.cpp

@@ -0,0 +1,357 @@
+/*************************************************************************/
+/*  callable.cpp                                                         */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "callable.h"
+#include "core/script_language.h"
+#include "message_queue.h"
+#include "object.h"
+#include "reference.h"
+
+void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const {
+	MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount);
+}
+
+void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
+
+	if (is_null()) {
+		r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+		r_call_error.argument = 0;
+		r_call_error.expected = 0;
+		r_return_value = Variant();
+	} else if (is_custom()) {
+		custom->call(p_arguments, p_argcount, r_return_value, r_call_error);
+	} else {
+		Object *obj = ObjectDB::get_instance(ObjectID(object));
+		r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error);
+	}
+}
+
+Object *Callable::get_object() const {
+	if (is_null()) {
+		return nullptr;
+	} else if (is_custom()) {
+		return ObjectDB::get_instance(custom->get_object());
+	} else {
+		return ObjectDB::get_instance(ObjectID(object));
+	}
+}
+
+ObjectID Callable::get_object_id() const {
+	if (is_null()) {
+		return ObjectID();
+	} else if (is_custom()) {
+		return custom->get_object();
+	} else {
+		return ObjectID(object);
+	}
+}
+StringName Callable::get_method() const {
+	ERR_FAIL_COND_V(is_custom(), StringName());
+	return method;
+}
+uint32_t Callable::hash() const {
+	if (is_custom()) {
+		return custom->hash();
+	} else {
+		uint32_t hash = method.hash();
+		return hash_djb2_one_64(object, hash);
+	}
+}
+
+bool Callable::operator==(const Callable &p_callable) const {
+	bool custom_a = is_custom();
+	bool custom_b = p_callable.is_custom();
+
+	if (custom_a == custom_b) {
+		if (custom_a) {
+			if (custom == p_callable.custom) {
+				return true; //same pointer, dont even compare
+			}
+
+			CallableCustom::CompareEqualFunc eq_a = custom->get_compare_equal_func();
+			CallableCustom::CompareEqualFunc eq_b = p_callable.custom->get_compare_equal_func();
+			if (eq_a == eq_b) {
+				return eq_a(custom, p_callable.custom);
+			} else {
+				return false;
+			}
+		} else {
+			return object == p_callable.object && method == p_callable.method;
+		}
+	} else {
+		return false;
+	}
+}
+bool Callable::operator!=(const Callable &p_callable) const {
+	return !(*this == p_callable);
+}
+bool Callable::operator<(const Callable &p_callable) const {
+	bool custom_a = is_custom();
+	bool custom_b = p_callable.is_custom();
+
+	if (custom_a == custom_b) {
+		if (custom_a) {
+			if (custom == p_callable.custom) {
+				return false; //same pointer, dont even compare
+			}
+
+			CallableCustom::CompareLessFunc less_a = custom->get_compare_less_func();
+			CallableCustom::CompareLessFunc less_b = p_callable.custom->get_compare_less_func();
+			if (less_a == less_b) {
+				return less_a(custom, p_callable.custom);
+			} else {
+				return less_a < less_b; //it's something..
+			}
+
+		} else {
+			if (object == p_callable.object) {
+				return method < p_callable.method;
+			} else {
+				return object < p_callable.object;
+			}
+		}
+	} else {
+		return int(custom_a ? 1 : 0) < int(custom_b ? 1 : 0);
+	}
+}
+
+void Callable::operator=(const Callable &p_callable) {
+	if (is_custom()) {
+		if (p_callable.is_custom()) {
+			if (custom == p_callable.custom) {
+				return;
+			}
+		}
+
+		if (custom->ref_count.unref()) {
+			memdelete(custom);
+		}
+	}
+
+	if (p_callable.is_custom()) {
+		method = StringName();
+		if (!p_callable.custom->ref_count.ref()) {
+			object = 0;
+		} else {
+			object = 0;
+			custom = p_callable.custom;
+		}
+	} else {
+		method = p_callable.method;
+		object = p_callable.object;
+	}
+}
+
+Callable::operator String() const {
+
+	if (is_custom()) {
+		return custom->get_as_text();
+	} else {
+		if (is_null()) {
+			return "null::null";
+		}
+
+		Object *base = get_object();
+		if (base) {
+			String class_name = base->get_class();
+			Ref<Script> script = base->get_script();
+			if (script.is_valid() && script->get_path().is_resource_file()) {
+
+				class_name += "(" + script->get_path().get_file() + ")";
+			}
+			return class_name + "::" + String(method);
+		} else {
+			return "null::" + String(method);
+		}
+	}
+}
+
+Callable::Callable(const Object *p_object, const StringName &p_method) {
+	if (p_method == StringName()) {
+		object = 0;
+		ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+	}
+	if (p_object == nullptr) {
+		object = 0;
+		ERR_FAIL_MSG("Object argument to Callable constructor must be non-null");
+	}
+
+	object = p_object->get_instance_id();
+	method = p_method;
+}
+
+Callable::Callable(ObjectID p_object, const StringName &p_method) {
+	if (p_method == StringName()) {
+		object = 0;
+		ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+	}
+
+	object = p_object;
+	method = p_method;
+}
+Callable::Callable(CallableCustom *p_custom) {
+	if (p_custom->referenced) {
+		object = 0;
+		ERR_FAIL_MSG("Callable custom is already referenced");
+	}
+	p_custom->referenced = true;
+	object = 0; //ensure object is all zero, since pointer may be 32 bits
+	custom = p_custom;
+}
+Callable::Callable(const Callable &p_callable) {
+	if (p_callable.is_custom()) {
+		if (!p_callable.custom->ref_count.ref()) {
+			object = 0;
+		} else {
+			object = 0;
+			custom = p_callable.custom;
+		}
+	} else {
+		method = p_callable.method;
+		object = p_callable.object;
+	}
+}
+
+Callable::~Callable() {
+	if (is_custom()) {
+		if (custom->ref_count.unref()) {
+			memdelete(custom);
+		}
+	}
+}
+
+Callable::Callable() {
+	object = 0;
+}
+
+CallableCustom::CallableCustom() {
+	referenced = false;
+	ref_count.init();
+}
+
+//////////////////////////////////
+
+Object *Signal::get_object() const {
+	return ObjectDB::get_instance(object);
+}
+ObjectID Signal::get_object_id() const {
+	return object;
+}
+StringName Signal::get_name() const {
+	return name;
+}
+
+bool Signal::operator==(const Signal &p_signal) const {
+	return object == p_signal.object && name == p_signal.name;
+}
+
+bool Signal::operator!=(const Signal &p_signal) const {
+	return object != p_signal.object || name != p_signal.name;
+}
+
+bool Signal::operator<(const Signal &p_signal) const {
+	if (object == p_signal.object) {
+		return name < p_signal.name;
+	} else {
+		return object < p_signal.object;
+	}
+}
+
+Signal::operator String() const {
+	Object *base = get_object();
+	if (base) {
+		String class_name = base->get_class();
+		Ref<Script> script = base->get_script();
+		if (script.is_valid() && script->get_path().is_resource_file()) {
+
+			class_name += "(" + script->get_path().get_file() + ")";
+		}
+		return class_name + "::[signal]" + String(name);
+	} else {
+		return "null::[signal]" + String(name);
+	}
+}
+
+Error Signal::emit(const Variant **p_arguments, int p_argcount) const {
+	Object *obj = ObjectDB::get_instance(object);
+	if (!obj) {
+		return ERR_INVALID_DATA;
+	}
+
+	return obj->emit_signal(name, p_arguments, p_argcount);
+}
+Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+	Object *object = get_object();
+	ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED);
+
+	return object->connect(name, p_callable, p_binds, p_flags);
+}
+void Signal::disconnect(const Callable &p_callable) {
+	Object *object = get_object();
+	ERR_FAIL_COND(!object);
+	object->disconnect(name, p_callable);
+}
+bool Signal::is_connected(const Callable &p_callable) const {
+	Object *object = get_object();
+	ERR_FAIL_COND_V(!object, false);
+
+	return object->is_connected(name, p_callable);
+}
+
+Array Signal::get_connections() const {
+	Object *object = get_object();
+	if (!object) {
+		return Array();
+	}
+
+	List<Object::Connection> connections;
+	object->get_signal_connection_list(name, &connections);
+
+	Array arr;
+	for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) {
+		arr.push_back(E->get());
+	}
+	return arr;
+}
+Signal::Signal(const Object *p_object, const StringName &p_name) {
+
+	ERR_FAIL_COND_MSG(p_object == nullptr, "Object argument to Signal constructor must be non-null");
+
+	object = p_object->get_instance_id();
+	name = p_name;
+}
+Signal::Signal(ObjectID p_object, const StringName &p_name) {
+
+	object = p_object;
+	name = p_name;
+}
+Signal::Signal() {
+}

+ 162 - 0
core/callable.h

@@ -0,0 +1,162 @@
+/*************************************************************************/
+/*  callable.h                                                           */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef CALLABLE_H
+#define CALLABLE_H
+
+#include "core/list.h"
+#include "core/object_id.h"
+#include "core/string_name.h"
+
+class Object;
+class Variant;
+class CallableCustom;
+
+// This is an abstraction of things that can be called
+// it is used for signals and other cases where effient
+// calling of functions is required.
+// It is designed for the standard case (object and method)
+// but can be optimized or customized.
+
+class Callable {
+
+	//needs to be max 16 bytes in 64 bits
+	StringName method;
+	union {
+		uint64_t object;
+		CallableCustom *custom;
+	};
+
+public:
+	struct CallError {
+		enum Error {
+			CALL_OK,
+			CALL_ERROR_INVALID_METHOD,
+			CALL_ERROR_INVALID_ARGUMENT, // expected is variant type
+			CALL_ERROR_TOO_MANY_ARGUMENTS, // expected is number of arguments
+			CALL_ERROR_TOO_FEW_ARGUMENTS, // expected is number of arguments
+			CALL_ERROR_INSTANCE_IS_NULL,
+		};
+		Error error;
+		int argument;
+		int expected;
+	};
+
+	void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const;
+	void call_deferred(const Variant **p_arguments, int p_argcount) const;
+
+	_FORCE_INLINE_ bool is_null() const {
+		return method == StringName() && object == 0;
+	}
+	_FORCE_INLINE_ bool is_custom() const {
+		return method == StringName() && custom != 0;
+	}
+	_FORCE_INLINE_ bool is_standard() const {
+		return method != StringName();
+	}
+
+	Object *get_object() const;
+	ObjectID get_object_id() const;
+	StringName get_method() const;
+
+	uint32_t hash() const;
+
+	bool operator==(const Callable &p_callable) const;
+	bool operator!=(const Callable &p_callable) const;
+	bool operator<(const Callable &p_callable) const;
+
+	void operator=(const Callable &p_callable);
+
+	operator String() const;
+
+	Callable(const Object *p_object, const StringName &p_method);
+	Callable(ObjectID p_object, const StringName &p_method);
+	Callable(CallableCustom *p_custom);
+	Callable(const Callable &p_callable);
+	Callable();
+	~Callable();
+};
+
+class CallableCustom {
+	friend class Callable;
+	SafeRefCount ref_count;
+	bool referenced;
+
+public:
+	typedef bool (*CompareEqualFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
+	typedef bool (*CompareLessFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
+
+	//for every type that inherits, these must always be the same for this type
+	virtual uint32_t hash() const = 0;
+	virtual String get_as_text() const = 0;
+	virtual CompareEqualFunc get_compare_equal_func() const = 0;
+	virtual CompareLessFunc get_compare_less_func() const = 0;
+	virtual ObjectID get_object() const = 0; //must always be able to provide an object
+	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
+
+	CallableCustom();
+	virtual ~CallableCustom() {}
+};
+
+// This is just a proxy object to object signals, its only
+// allocated on demand by/for scripting languages so it can
+// be put inside a Variant, but it is not
+// used by the engine itself.
+
+class Signal {
+	StringName name;
+	ObjectID object;
+
+public:
+	_FORCE_INLINE_ bool is_null() const {
+		return object.is_null() && name == StringName();
+	}
+	Object *get_object() const;
+	ObjectID get_object_id() const;
+	StringName get_name() const;
+
+	bool operator==(const Signal &p_signal) const;
+	bool operator!=(const Signal &p_signal) const;
+	bool operator<(const Signal &p_signal) const;
+
+	operator String() const;
+
+	Error emit(const Variant **p_arguments, int p_argcount) const;
+	Error connect(const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+	void disconnect(const Callable &p_callable);
+	bool is_connected(const Callable &p_callable) const;
+
+	Array get_connections() const;
+	Signal(const Object *p_object, const StringName &p_name);
+	Signal(ObjectID p_object, const StringName &p_name);
+	Signal();
+};
+
+#endif // CALLABLE_H

+ 15 - 5
core/class_db.cpp

@@ -1033,7 +1033,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
 				return true; //return true but do nothing
 			}
 
-			Variant::CallError ce;
+			Callable::CallError ce;
 
 			if (psg->index >= 0) {
 				Variant index = psg->index;
@@ -1055,7 +1055,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
 			}
 
 			if (r_valid)
-				*r_valid = ce.error == Variant::CallError::CALL_OK;
+				*r_valid = ce.error == Callable::CallError::CALL_OK;
 
 			return true;
 		}
@@ -1078,12 +1078,12 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
 			if (psg->index >= 0) {
 				Variant index = psg->index;
 				const Variant *arg[1] = { &index };
-				Variant::CallError ce;
+				Callable::CallError ce;
 				r_value = p_object->call(psg->getter, arg, 1, ce);
 
 			} else {
 
-				Variant::CallError ce;
+				Callable::CallError ce;
 				if (psg->_getptr) {
 
 					r_value = psg->_getptr->call(p_object, NULL, 0, ce);
@@ -1094,13 +1094,23 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
 			return true;
 		}
 
-		const int *c = check->constant_map.getptr(p_property);
+		const int *c = check->constant_map.getptr(p_property); //constants count
 		if (c) {
 
 			r_value = *c;
 			return true;
 		}
 
+		if (check->method_map.has(p_property)) { //methods count
+			r_value = Callable(p_object, p_property);
+			return true;
+		}
+
+		if (check->signal_map.has(p_property)) { //signals count
+			r_value = Signal(p_object, p_property);
+			return true;
+		}
+
 		check = check->inherits_ptr;
 	}
 

+ 5 - 1
core/core_string_names.cpp

@@ -70,5 +70,9 @@ CoreStringNames::CoreStringNames() :
 		r8(StaticCString::create("r8")),
 		g8(StaticCString::create("g8")),
 		b8(StaticCString::create("b8")),
-		a8(StaticCString::create("a8")) {
+		a8(StaticCString::create("a8")),
+		call(StaticCString::create("call")),
+		call_deferred(StaticCString::create("call_deferred")),
+		emit(StaticCString::create("emit")),
+		notification(StaticCString::create("notification")) {
 }

+ 5 - 0
core/core_string_names.h

@@ -90,6 +90,11 @@ public:
 	StringName g8;
 	StringName b8;
 	StringName a8;
+
+	StringName call;
+	StringName call_deferred;
+	StringName emit;
+	StringName notification;
 };
 
 #endif // SCENE_STRING_NAMES_H

+ 3 - 3
core/func_ref.cpp

@@ -30,16 +30,16 @@
 
 #include "func_ref.h"
 
-Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	if (id.is_null()) {
-		r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+		r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
 		return Variant();
 	}
 	Object *obj = ObjectDB::get_instance(id);
 
 	if (!obj) {
-		r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+		r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
 		return Variant();
 	}
 

+ 1 - 1
core/func_ref.h

@@ -43,7 +43,7 @@ protected:
 	static void _bind_methods();
 
 public:
-	Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+	Variant call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Variant call_funcv(const Array &p_args);
 	void set_instance(Object *p_obj);
 	void set_function(const StringName &p_func);

+ 2 - 0
core/global_constants.cpp

@@ -609,6 +609,8 @@ void register_global_constants() {
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); // 15
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RID", Variant::_RID);
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_OBJECT", Variant::OBJECT);
+	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_CALLABLE", Variant::CALLABLE);
+	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL);
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); // 20
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY);
 	BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY);

+ 2 - 2
core/io/dtls_server.cpp

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 2 - 2
core/io/dtls_server.h

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 15 - 0
core/io/marshalls.cpp

@@ -455,6 +455,15 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
 			}
 
 		} break;
+		case Variant::CALLABLE: {
+
+			r_variant = Callable();
+		} break;
+		case Variant::SIGNAL: {
+
+			r_variant = Signal();
+		} break;
+
 		case Variant::DICTIONARY: {
 
 			ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -1074,6 +1083,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
 		} break;
 		case Variant::_RID: {
 
+		} break;
+		case Variant::CALLABLE: {
+
+		} break;
+		case Variant::SIGNAL: {
+
 		} break;
 		case Variant::OBJECT: {
 

+ 17 - 17
core/io/multiplayer_api.cpp

@@ -145,22 +145,22 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee
 			"Supplied NetworkedMultiplayerPeer must be connecting or connected.");
 
 	if (network_peer.is_valid()) {
-		network_peer->disconnect("peer_connected", this, "_add_peer");
-		network_peer->disconnect("peer_disconnected", this, "_del_peer");
-		network_peer->disconnect("connection_succeeded", this, "_connected_to_server");
-		network_peer->disconnect("connection_failed", this, "_connection_failed");
-		network_peer->disconnect("server_disconnected", this, "_server_disconnected");
+		network_peer->disconnect_compat("peer_connected", this, "_add_peer");
+		network_peer->disconnect_compat("peer_disconnected", this, "_del_peer");
+		network_peer->disconnect_compat("connection_succeeded", this, "_connected_to_server");
+		network_peer->disconnect_compat("connection_failed", this, "_connection_failed");
+		network_peer->disconnect_compat("server_disconnected", this, "_server_disconnected");
 		clear();
 	}
 
 	network_peer = p_peer;
 
 	if (network_peer.is_valid()) {
-		network_peer->connect("peer_connected", this, "_add_peer");
-		network_peer->connect("peer_disconnected", this, "_del_peer");
-		network_peer->connect("connection_succeeded", this, "_connected_to_server");
-		network_peer->connect("connection_failed", this, "_connection_failed");
-		network_peer->connect("server_disconnected", this, "_server_disconnected");
+		network_peer->connect_compat("peer_connected", this, "_add_peer");
+		network_peer->connect_compat("peer_disconnected", this, "_del_peer");
+		network_peer->connect_compat("connection_succeeded", this, "_connected_to_server");
+		network_peer->connect_compat("connection_failed", this, "_connection_failed");
+		network_peer->connect_compat("server_disconnected", this, "_server_disconnected");
 	}
 }
 
@@ -368,10 +368,10 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
 		p_offset += vlen;
 	}
 
-	Variant::CallError ce;
+	Callable::CallError ce;
 
 	p_node->call(name, (const Variant **)argp.ptr(), argc, ce);
-	if (ce.error != Variant::CallError::CALL_OK) {
+	if (ce.error != Callable::CallError::CALL_OK) {
 		String error = Variant::get_call_error_text(p_node, name, (const Variant **)argp.ptr(), argc, ce);
 		error = "RPC - " + error;
 		ERR_PRINT(error);
@@ -989,10 +989,10 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
 	if (call_local_native) {
 		int temp_id = rpc_sender_id;
 		rpc_sender_id = get_network_unique_id();
-		Variant::CallError ce;
+		Callable::CallError ce;
 		p_node->call(p_method, p_arg, p_argcount, ce);
 		rpc_sender_id = temp_id;
-		if (ce.error != Variant::CallError::CALL_OK) {
+		if (ce.error != Callable::CallError::CALL_OK) {
 			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
 			error = "rpc() aborted in local call:  - " + error + ".";
 			ERR_PRINT(error);
@@ -1003,11 +1003,11 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
 	if (call_local_script) {
 		int temp_id = rpc_sender_id;
 		rpc_sender_id = get_network_unique_id();
-		Variant::CallError ce;
-		ce.error = Variant::CallError::CALL_OK;
+		Callable::CallError ce;
+		ce.error = Callable::CallError::CALL_OK;
 		p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
 		rpc_sender_id = temp_id;
-		if (ce.error != Variant::CallError::CALL_OK) {
+		if (ce.error != Callable::CallError::CALL_OK) {
 			String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
 			error = "rpc() aborted in script local call:  - " + error + ".";
 			ERR_PRINT(error);

+ 2 - 2
core/io/packet_peer_dtls.cpp

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 2 - 2
core/io/packet_peer_dtls.h

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 22 - 0
core/io/resource_format_binary.cpp

@@ -73,6 +73,8 @@ enum {
 	VARIANT_VECTOR2_ARRAY = 37,
 	VARIANT_INT64 = 40,
 	VARIANT_DOUBLE = 41,
+	VARIANT_CALLABLE = 42,
+	VARIANT_SIGNAL = 43,
 	OBJECT_EMPTY = 0,
 	OBJECT_EXTERNAL_RESOURCE = 1,
 	OBJECT_INTERNAL_RESOURCE = 2,
@@ -363,6 +365,15 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
 			}
 
 		} break;
+		case VARIANT_CALLABLE: {
+
+			r_v = Callable();
+		} break;
+		case VARIANT_SIGNAL: {
+
+			r_v = Signal();
+		} break;
+
 		case VARIANT_DICTIONARY: {
 
 			uint32_t len = f->get_32();
@@ -1440,6 +1451,17 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
 			}
 
 		} break;
+		case Variant::CALLABLE: {
+
+			f->store_32(VARIANT_CALLABLE);
+			WARN_PRINT("Can't save Callables.");
+		} break;
+		case Variant::SIGNAL: {
+
+			f->store_32(VARIANT_SIGNAL);
+			WARN_PRINT("Can't save Signals.");
+		} break;
+
 		case Variant::DICTIONARY: {
 
 			f->store_32(VARIANT_DICTIONARY);

+ 2 - 2
core/io/udp_server.cpp

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 2 - 2
core/io/udp_server.h

@@ -5,8 +5,8 @@
 /*                           GODOT ENGINE                                */
 /*                      https://godotengine.org                          */
 /*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
 /*                                                                       */
 /* Permission is hereby granted, free of charge, to any person obtaining */
 /* a copy of this software and associated documentation files (the       */

+ 12 - 12
core/make_binders.py

@@ -32,22 +32,22 @@ public:
 		return T::get_class_static();
 	}
 
-	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
 
 		T *instance=Object::cast_to<T>(p_object);
-		r_error.error=Variant::CallError::CALL_OK;
+		r_error.error=Callable::CallError::CALL_OK;
 #ifdef DEBUG_METHODS_ENABLED
 
 		ERR_FAIL_COND_V(!instance,Variant());
 		if (p_arg_count>get_argument_count()) {
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 			r_error.argument=get_argument_count();
 			return Variant();
 
 		}
 		if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
 
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 			r_error.argument=get_argument_count()-get_default_argument_count();
 			return Variant();
 		}
@@ -126,23 +126,23 @@ public:
 		return type_name;
 	}
 
-	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
 
 		__UnexistingClass *instance = (__UnexistingClass*)p_object;
 
-		r_error.error=Variant::CallError::CALL_OK;
+		r_error.error=Callable::CallError::CALL_OK;
 #ifdef DEBUG_METHODS_ENABLED
 
 		ERR_FAIL_COND_V(!instance,Variant());
 		if (p_arg_count>get_argument_count()) {
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 			r_error.argument=get_argument_count();
 			return Variant();
 		}
 
 		if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
 
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 			r_error.argument=get_argument_count()-get_default_argument_count();
 			return Variant();
 		}
@@ -223,22 +223,22 @@ public:
 		return T::get_class_static();
 	}
 
-	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+	virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
 
 		T *instance=Object::cast_to<T>(p_object);
-		r_error.error=Variant::CallError::CALL_OK;
+		r_error.error=Callable::CallError::CALL_OK;
 #ifdef DEBUG_METHODS_ENABLED
 
 		ERR_FAIL_COND_V(!instance,Variant());
 		if (p_arg_count>get_argument_count()) {
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 			r_error.argument=get_argument_count();
 			return Variant();
 
 		}
 		if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
 
-			r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+			r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 			r_error.argument=get_argument_count()-get_default_argument_count();
 			return Variant();
 		}

+ 27 - 27
core/math/expression.cpp

@@ -208,16 +208,16 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
 	return 0;
 }
 
-#define VALIDATE_ARG_NUM(m_arg)                                          \
-	if (!p_inputs[m_arg]->is_num()) {                                    \
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
-		r_error.argument = m_arg;                                        \
-		r_error.expected = Variant::REAL;                                \
-		return;                                                          \
+#define VALIDATE_ARG_NUM(m_arg)                                           \
+	if (!p_inputs[m_arg]->is_num()) {                                     \
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+		r_error.argument = m_arg;                                         \
+		r_error.expected = Variant::REAL;                                 \
+		return;                                                           \
 	}
 
-void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str) {
-	r_error.error = Variant::CallError::CALL_OK;
+void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
+	r_error.error = Callable::CallError::CALL_OK;
 	switch (p_func) {
 		case MATH_SIN: {
 
@@ -320,7 +320,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 				*r_return = Math::abs(r);
 			} else {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::REAL;
 			}
@@ -337,7 +337,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 				*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
 			} else {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::REAL;
 			}
@@ -580,7 +580,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 
 			if (p_inputs[0]->get_type() != Variant::OBJECT) {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::OBJECT;
 
@@ -614,7 +614,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 
 			if (p_inputs[0]->get_type() != Variant::OBJECT) {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::OBJECT;
 
@@ -622,7 +622,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 			}
 			if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 1;
 				r_error.expected = Variant::STRING;
 
@@ -644,7 +644,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 			if (type < 0 || type >= Variant::VARIANT_MAX) {
 
 				r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::INT;
 				return;
@@ -675,7 +675,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 
 			if (p_inputs[0]->get_type() != Variant::STRING) {
 
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::STRING;
 
@@ -687,7 +687,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 			if (str.length() != 1) {
 
 				r_error_str = RTR("Expected a string of length 1 (a character).");
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::STRING;
 
@@ -732,7 +732,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 		case STR_TO_VAR: {
 
 			if (p_inputs[0]->get_type() != Variant::STRING) {
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::STRING;
 
@@ -747,7 +747,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 			Error err = VariantParser::parse(&ss, *r_return, errs, line);
 
 			if (err != OK) {
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::STRING;
 				*r_return = "Parse error at line " + itos(line) + ": " + errs;
@@ -762,7 +762,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 			int len;
 			Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
 			if (err) {
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::NIL;
 				r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
@@ -779,7 +779,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 		case BYTES_TO_VAR: {
 
 			if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
-				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 				r_error.argument = 0;
 				r_error.expected = Variant::PACKED_BYTE_ARRAY;
 
@@ -794,7 +794,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
 				Error err = decode_variant(ret, r, varr.size(), NULL, allow_objects);
 				if (err != OK) {
 					r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
-					r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+					r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument = 0;
 					r_error.expected = Variant::PACKED_BYTE_ARRAY;
 					return;
@@ -2071,10 +2071,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
 				argp.write[i] = &arr[i];
 			}
 
-			Variant::CallError ce;
+			Callable::CallError ce;
 			r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce);
 
-			if (ce.error != Variant::CallError::CALL_OK) {
+			if (ce.error != Callable::CallError::CALL_OK) {
 				r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type));
 				return true;
 			}
@@ -2099,10 +2099,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
 				argp.write[i] = &arr[i];
 			}
 
-			Variant::CallError ce;
+			Callable::CallError ce;
 			exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
 
-			if (ce.error != Variant::CallError::CALL_OK) {
+			if (ce.error != Callable::CallError::CALL_OK) {
 				r_error_str = "Builtin Call Failed. " + r_error_str;
 				return true;
 			}
@@ -2134,10 +2134,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
 				argp.write[i] = &arr[i];
 			}
 
-			Variant::CallError ce;
+			Callable::CallError ce;
 			r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce);
 
-			if (ce.error != Variant::CallError::CALL_OK) {
+			if (ce.error != Callable::CallError::CALL_OK) {
 				r_error_str = vformat(RTR("On call to '%s':"), String(call->method));
 				return true;
 			}

+ 1 - 1
core/math/expression.h

@@ -111,7 +111,7 @@ public:
 
 	static int get_func_argument_count(BuiltinFunc p_func);
 	static String get_func_name(BuiltinFunc p_func);
-	static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str);
+	static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str);
 	static BuiltinFunc find_function(const String &p_string);
 
 private:

+ 54 - 51
core/message_queue.cpp

@@ -30,6 +30,7 @@
 
 #include "message_queue.h"
 
+#include "core/core_string_names.h"
 #include "core/project_settings.h"
 #include "core/script_language.h"
 
@@ -42,37 +43,7 @@ MessageQueue *MessageQueue::get_singleton() {
 
 Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) {
 
-	_THREAD_SAFE_METHOD_
-
-	int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
-
-	if ((buffer_end + room_needed) >= buffer_size) {
-		String type;
-		if (ObjectDB::get_instance(p_id))
-			type = ObjectDB::get_instance(p_id)->get_class();
-		print_line("Failed method: " + type + ":" + p_method + " target ID: " + itos(p_id));
-		statistics();
-		ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
-	}
-
-	Message *msg = memnew_placement(&buffer[buffer_end], Message);
-	msg->args = p_argcount;
-	msg->instance_id = p_id;
-	msg->target = p_method;
-	msg->type = TYPE_CALL;
-	if (p_show_error)
-		msg->type |= FLAG_SHOW_ERROR;
-
-	buffer_end += sizeof(Message);
-
-	for (int i = 0; i < p_argcount; i++) {
-
-		Variant *v = memnew_placement(&buffer[buffer_end], Variant);
-		buffer_end += sizeof(Variant);
-		*v = *p_args[i];
-	}
-
-	return OK;
+	return push_callable(Callable(p_id, p_method), p_args, p_argcount, p_show_error);
 }
 
 Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
@@ -107,8 +78,7 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
 
 	Message *msg = memnew_placement(&buffer[buffer_end], Message);
 	msg->args = 1;
-	msg->instance_id = p_id;
-	msg->target = p_prop;
+	msg->callable = Callable(p_id, p_prop);
 	msg->type = TYPE_SET;
 
 	buffer_end += sizeof(Message);
@@ -137,7 +107,7 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
 	Message *msg = memnew_placement(&buffer[buffer_end], Message);
 
 	msg->type = TYPE_NOTIFICATION;
-	msg->instance_id = p_id;
+	msg->callable = Callable(p_id, CoreStringNames::get_singleton()->notification); //name is meaningless but callable needs it
 	//msg->target;
 	msg->notification = p_notification;
 
@@ -160,18 +130,49 @@ Error MessageQueue::push_set(Object *p_object, const StringName &p_prop, const V
 	return push_set(p_object->get_instance_id(), p_prop, p_value);
 }
 
+Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error) {
+
+	_THREAD_SAFE_METHOD_
+
+	int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
+
+	if ((buffer_end + room_needed) >= buffer_size) {
+		print_line("Failed method: " + p_callable);
+		statistics();
+		ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
+	}
+
+	Message *msg = memnew_placement(&buffer[buffer_end], Message);
+	msg->args = p_argcount;
+	msg->callable = p_callable;
+	msg->type = TYPE_CALL;
+	if (p_show_error)
+		msg->type |= FLAG_SHOW_ERROR;
+
+	buffer_end += sizeof(Message);
+
+	for (int i = 0; i < p_argcount; i++) {
+
+		Variant *v = memnew_placement(&buffer[buffer_end], Variant);
+		buffer_end += sizeof(Variant);
+		*v = *p_args[i];
+	}
+
+	return OK;
+}
+
 void MessageQueue::statistics() {
 
 	Map<StringName, int> set_count;
 	Map<int, int> notify_count;
-	Map<StringName, int> call_count;
+	Map<Callable, int> call_count;
 	int null_count = 0;
 
 	uint32_t read_pos = 0;
 	while (read_pos < buffer_end) {
 		Message *message = (Message *)&buffer[read_pos];
 
-		Object *target = ObjectDB::get_instance(message->instance_id);
+		Object *target = message->callable.get_object();
 
 		if (target != NULL) {
 
@@ -179,10 +180,10 @@ void MessageQueue::statistics() {
 
 				case TYPE_CALL: {
 
-					if (!call_count.has(message->target))
-						call_count[message->target] = 0;
+					if (!call_count.has(message->callable))
+						call_count[message->callable] = 0;
 
-					call_count[message->target]++;
+					call_count[message->callable]++;
 
 				} break;
 				case TYPE_NOTIFICATION: {
@@ -195,10 +196,11 @@ void MessageQueue::statistics() {
 				} break;
 				case TYPE_SET: {
 
-					if (!set_count.has(message->target))
-						set_count[message->target] = 0;
+					StringName t = message->callable.get_method();
+					if (!set_count.has(t))
+						set_count[t] = 0;
 
-					set_count[message->target]++;
+					set_count[t]++;
 
 				} break;
 			}
@@ -222,7 +224,7 @@ void MessageQueue::statistics() {
 		print_line("SET " + E->key() + ": " + itos(E->get()));
 	}
 
-	for (Map<StringName, int>::Element *E = call_count.front(); E; E = E->next()) {
+	for (Map<Callable, int>::Element *E = call_count.front(); E; E = E->next()) {
 		print_line("CALL " + E->key() + ": " + itos(E->get()));
 	}
 
@@ -236,7 +238,7 @@ int MessageQueue::get_max_buffer_usage() const {
 	return buffer_max_used;
 }
 
-void MessageQueue::_call_function(Object *p_target, const StringName &p_func, const Variant *p_args, int p_argcount, bool p_show_error) {
+void MessageQueue::_call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error) {
 
 	const Variant **argptrs = NULL;
 	if (p_argcount) {
@@ -246,11 +248,12 @@ void MessageQueue::_call_function(Object *p_target, const StringName &p_func, co
 		}
 	}
 
-	Variant::CallError ce;
-	p_target->call(p_func, argptrs, p_argcount, ce);
-	if (p_show_error && ce.error != Variant::CallError::CALL_OK) {
+	Callable::CallError ce;
+	Variant ret;
+	p_callable.call(argptrs, p_argcount, ret, ce);
+	if (p_show_error && ce.error != Callable::CallError::CALL_OK) {
 
-		ERR_PRINT("Error calling deferred method: " + Variant::get_call_error_text(p_target, p_func, argptrs, p_argcount, ce) + ".");
+		ERR_PRINT("Error calling deferred method: " + Variant::get_callable_error_text(p_callable, argptrs, p_argcount, ce) + ".");
 	}
 }
 
@@ -283,7 +286,7 @@ void MessageQueue::flush() {
 
 		_THREAD_SAFE_UNLOCK_
 
-		Object *target = ObjectDB::get_instance(message->instance_id);
+		Object *target = message->callable.get_object();
 
 		if (target != NULL) {
 
@@ -294,7 +297,7 @@ void MessageQueue::flush() {
 
 					// messages don't expect a return value
 
-					_call_function(target, message->target, args, message->args, message->type & FLAG_SHOW_ERROR);
+					_call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
 
 				} break;
 				case TYPE_NOTIFICATION: {
@@ -307,7 +310,7 @@ void MessageQueue::flush() {
 
 					Variant *arg = (Variant *)(message + 1);
 					// messages don't expect a return value
-					target->set(message->target, *arg);
+					target->set(message->callable.get_method(), *arg);
 
 				} break;
 			}

+ 3 - 3
core/message_queue.h

@@ -54,8 +54,7 @@ class MessageQueue {
 
 	struct Message {
 
-		ObjectID instance_id;
-		StringName target;
+		Callable callable;
 		int16_t type;
 		union {
 			int16_t notification;
@@ -68,7 +67,7 @@ class MessageQueue {
 	uint32_t buffer_max_used;
 	uint32_t buffer_size;
 
-	void _call_function(Object *p_target, const StringName &p_func, const Variant *p_args, int p_argcount, bool p_show_error);
+	void _call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error);
 
 	static MessageQueue *singleton;
 
@@ -81,6 +80,7 @@ public:
 	Error push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_LIST);
 	Error push_notification(ObjectID p_id, int p_notification);
 	Error push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value);
+	Error push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error = false);
 
 	Error push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST);
 	Error push_notification(Object *p_object, int p_notification);

+ 5 - 5
core/method_bind.h

@@ -155,7 +155,7 @@ struct VariantObjectClassChecker<Control *> {
 		Variant::Type argtype = get_argument_type(m_arg - 1);                       \
 		if (!Variant::can_convert_strict(p_args[m_arg - 1]->get_type(), argtype) || \
 				!VariantObjectClassChecker<P##m_arg>::check(*p_args[m_arg - 1])) {  \
-			r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;        \
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;       \
 			r_error.argument = m_arg - 1;                                           \
 			r_error.expected = argtype;                                             \
 			return Variant();                                                       \
@@ -278,7 +278,7 @@ public:
 
 	_FORCE_INLINE_ int get_argument_count() const { return argument_count; };
 
-	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) = 0;
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) = 0;
 
 #ifdef PTRCALL_ENABLED
 	virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) = 0;
@@ -300,7 +300,7 @@ public:
 template <class T>
 class MethodBindVarArg : public MethodBind {
 public:
-	typedef Variant (T::*NativeCall)(const Variant **, int, Variant::CallError &);
+	typedef Variant (T::*NativeCall)(const Variant **, int, Callable::CallError &);
 
 protected:
 	NativeCall call_method;
@@ -338,7 +338,7 @@ public:
 	}
 
 #endif
-	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) {
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
 
 		T *instance = static_cast<T *>(p_object);
 		return (instance->*call_method)(p_args, p_arg_count, r_error);
@@ -389,7 +389,7 @@ public:
 };
 
 template <class T>
-MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Variant::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
+MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
 
 	MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
 	a->set_method(p_method);

+ 2 - 0
core/method_ptrcall.h

@@ -128,6 +128,8 @@ MAKE_PTRARG_BY_REFERENCE(Color);
 MAKE_PTRARG(NodePath);
 MAKE_PTRARG(RID);
 MAKE_PTRARG(Dictionary);
+MAKE_PTRARG(Callable);
+MAKE_PTRARG(Signal);
 MAKE_PTRARG(Array);
 MAKE_PTRARG(PackedByteArray);
 MAKE_PTRARG(PackedIntArray);

+ 114 - 130
core/object.cpp

@@ -335,10 +335,8 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
 Object::Connection::operator Variant() const {
 
 	Dictionary d;
-	d["source"] = source;
 	d["signal"] = signal;
-	d["target"] = target;
-	d["method"] = method;
+	d["callable"] = callable;
 	d["flags"] = flags;
 	d["binds"] = binds;
 	return d;
@@ -346,34 +344,19 @@ Object::Connection::operator Variant() const {
 
 bool Object::Connection::operator<(const Connection &p_conn) const {
 
-	if (source == p_conn.source) {
-
-		if (signal == p_conn.signal) {
-
-			if (target == p_conn.target) {
-
-				return method < p_conn.method;
-			} else {
-
-				return target < p_conn.target;
-			}
-		} else
-			return signal < p_conn.signal;
+	if (signal == p_conn.signal) {
+		return callable < p_conn.callable;
 	} else {
-		return source < p_conn.source;
+		return signal < p_conn.signal;
 	}
 }
 Object::Connection::Connection(const Variant &p_variant) {
 
 	Dictionary d = p_variant;
-	if (d.has("source"))
-		source = d["source"];
 	if (d.has("signal"))
 		signal = d["signal"];
-	if (d.has("target"))
-		target = d["target"];
-	if (d.has("method"))
-		method = d["method"];
+	if (d.has("callable"))
+		callable = d["callable"];
 	if (d.has("flags"))
 		flags = d["flags"];
 	if (d.has("binds"))
@@ -655,16 +638,16 @@ void Object::get_method_list(List<MethodInfo> *p_list) const {
 	}
 }
 
-Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	if (p_argcount < 1) {
-		r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 		r_error.argument = 0;
 		return Variant();
 	}
 
 	if (p_args[0]->get_type() != Variant::STRING) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 0;
 		r_error.expected = Variant::STRING;
 		return Variant();
@@ -675,22 +658,22 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::Call
 	return call(method, &p_args[1], p_argcount - 1, r_error);
 }
 
-Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	if (p_argcount < 1) {
-		r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 		r_error.argument = 0;
 		return Variant();
 	}
 
 	if (p_args[0]->get_type() != Variant::STRING) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 0;
 		r_error.expected = Variant::STRING;
 		return Variant();
 	}
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 
 	StringName method = *p_args[0];
 
@@ -700,29 +683,29 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Vari
 }
 
 #ifdef DEBUG_ENABLED
-static void _test_call_error(const StringName &p_func, const Variant::CallError &error) {
+static void _test_call_error(const StringName &p_func, const Callable::CallError &error) {
 
 	switch (error.error) {
 
-		case Variant::CallError::CALL_OK:
-		case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+		case Callable::CallError::CALL_OK:
+		case Callable::CallError::CALL_ERROR_INVALID_METHOD:
 			break;
-		case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+		case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
 
-			ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected) + ".");
+			ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(Variant::Type(error.expected)) + ".");
 			break;
 		}
-		case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+		case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
 
 			ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument) + ".");
 			break;
 		}
-		case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+		case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
 
 			ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument) + ".");
 			break;
 		}
-		case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
+		case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL:
 			break;
 	}
 }
@@ -749,7 +732,7 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
 	//Variant ret;
 	OBJ_DEBUG_LOCK
 
-	Variant::CallError error;
+	Callable::CallError error;
 
 	if (script_instance) {
 		script_instance->call_multilevel(p_method, p_args, p_argcount);
@@ -769,7 +752,7 @@ void Object::call_multilevel_reversed(const StringName &p_method, const Variant
 
 	MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
 
-	Variant::CallError error;
+	Callable::CallError error;
 	OBJ_DEBUG_LOCK
 
 	if (method) {
@@ -823,9 +806,9 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
 		}
 	}
 
-	Variant::CallError ce;
+	Callable::CallError ce;
 	Variant ret = call(p_method, argptrs, p_args.size(), ce);
-	if (ce.error != Variant::CallError::CALL_OK) {
+	if (ce.error != Callable::CallError::CALL_OK) {
 		ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + ".");
 	}
 	return ret;
@@ -842,7 +825,7 @@ Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
 		argc++;
 	}
 
-	Variant::CallError error;
+	Callable::CallError error;
 
 	Variant ret = call(p_name, argptr, argc, error);
 	return ret;
@@ -859,38 +842,38 @@ void Object::call_multilevel(const StringName &p_name, VARIANT_ARG_DECLARE) {
 		argc++;
 	}
 
-	//Variant::CallError error;
+	//Callable::CallError error;
 	call_multilevel(p_name, argptr, argc);
 }
 
-Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 
 	if (p_method == CoreStringNames::get_singleton()->_free) {
 //free must be here, before anything, always ready
 #ifdef DEBUG_ENABLED
 		if (p_argcount != 0) {
 			r_error.argument = 0;
-			r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+			r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 			return Variant();
 		}
 		if (Object::cast_to<Reference>(this)) {
 			r_error.argument = 0;
-			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
 			ERR_FAIL_V_MSG(Variant(), "Can't 'free' a reference.");
 		}
 
 		if (_lock_index.get() > 1) {
 			r_error.argument = 0;
-			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
 			ERR_FAIL_V_MSG(Variant(), "Object is locked and can't be freed.");
 		}
 
 #endif
 		//must be here, must be before everything,
 		memdelete(this);
-		r_error.error = Variant::CallError::CALL_OK;
+		r_error.error = Callable::CallError::CALL_OK;
 		return Variant();
 	}
 
@@ -901,15 +884,15 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
 		//force jumptable
 		switch (r_error.error) {
 
-			case Variant::CallError::CALL_OK:
+			case Callable::CallError::CALL_OK:
 				return ret;
-			case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+			case Callable::CallError::CALL_ERROR_INVALID_METHOD:
 				break;
-			case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT:
-			case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
-			case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
+			case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
+			case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
+			case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
 				return ret;
-			case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
+			case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
 			}
 		}
 	}
@@ -919,7 +902,7 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
 	if (method) {
 		ret = method->call(this, p_args, p_argcount, r_error);
 	} else {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
 	}
 
 	return ret;
@@ -1102,7 +1085,7 @@ void Object::add_user_signal(const MethodInfo &p_signal) {
 	ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
 	ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
 	ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
-	Signal s;
+	SignalData s;
 	s.user = p_signal;
 	signal_map[p_signal.name] = s;
 }
@@ -1117,23 +1100,22 @@ bool Object::_has_user_signal(const StringName &p_name) const {
 struct _ObjectSignalDisconnectData {
 
 	StringName signal;
-	Object *target;
-	StringName method;
+	Callable callable;
 };
 
-Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
-	r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+	r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 
 	ERR_FAIL_COND_V(p_argcount < 1, Variant());
 	if (p_args[0]->get_type() != Variant::STRING) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 0;
 		r_error.expected = Variant::STRING;
 		ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING, Variant());
 	}
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 
 	StringName signal = *p_args[0];
 
@@ -1154,7 +1136,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 	if (_block_signals)
 		return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked
 
-	Signal *s = signal_map.getptr(p_name);
+	SignalData *s = signal_map.getptr(p_name);
 	if (!s) {
 #ifdef DEBUG_ENABLED
 		bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name);
@@ -1170,7 +1152,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 	//copy on write will ensure that disconnecting the signal or even deleting the object will not affect the signal calling.
 	//this happens automatically and will not change the performance of calling.
 	//awesome, isn't it?
-	VMap<Signal::Target, Signal::Slot> slot_map = s->slot_map;
+	VMap<Callable, SignalData::Slot> slot_map = s->slot_map;
 
 	int ssize = slot_map.size();
 
@@ -1184,7 +1166,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 
 		const Connection &c = slot_map.getv(i).conn;
 
-		Object *target = ObjectDB::get_instance(slot_map.getk(i)._id);
+		Object *target = c.callable.get_object();
 		if (!target) {
 			// Target might have been deleted during signal callback, this is expected and OK.
 			continue;
@@ -1209,22 +1191,23 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 		}
 
 		if (c.flags & CONNECT_DEFERRED) {
-			MessageQueue::get_singleton()->push_call(target->get_instance_id(), c.method, args, argc, true);
+			MessageQueue::get_singleton()->push_callable(c.callable, args, argc, true);
 		} else {
-			Variant::CallError ce;
+			Callable::CallError ce;
 			_emitting = true;
-			target->call(c.method, args, argc, ce);
+			Variant ret;
+			c.callable.call(args, argc, ret, ce);
 			_emitting = false;
 
-			if (ce.error != Variant::CallError::CALL_OK) {
+			if (ce.error != Callable::CallError::CALL_OK) {
 #ifdef DEBUG_ENABLED
 				if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool()))
 					continue;
 #endif
-				if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
+				if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
 					//most likely object is not initialized yet, do not throw error.
 				} else {
-					ERR_PRINT("Error calling method from signal '" + String(p_name) + "': " + Variant::get_call_error_text(target, c.method, args, argc, ce) + ".");
+					ERR_PRINT("Error calling from signal '" + String(p_name) + "': " + Variant::get_callable_error_text(c.callable, args, argc, ce) + ".");
 					err = ERR_METHOD_NOT_FOUND;
 				}
 			}
@@ -1241,8 +1224,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 
 			_ObjectSignalDisconnectData dd;
 			dd.signal = p_name;
-			dd.target = target;
-			dd.method = c.method;
+			dd.callable = c.callable;
 			disconnect_data.push_back(dd);
 		}
 	}
@@ -1250,7 +1232,8 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
 	while (!disconnect_data.empty()) {
 
 		const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
-		disconnect(dd.signal, dd.target, dd.method);
+
+		_disconnect(dd.signal, dd.callable);
 		disconnect_data.pop_front();
 	}
 
@@ -1322,15 +1305,8 @@ Array Object::_get_signal_connection_list(const String &p_signal) const {
 	for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
 
 		Connection &c = E->get();
-		if (c.signal == p_signal) {
-			Dictionary rc;
-			rc["signal"] = c.signal;
-			rc["method"] = c.method;
-			rc["source"] = c.source;
-			rc["target"] = c.target;
-			rc["binds"] = c.binds;
-			rc["flags"] = c.flags;
-			ret.push_back(rc);
+		if (c.signal.get_name() == p_signal) {
+			ret.push_back(c);
 		}
 	}
 
@@ -1342,11 +1318,7 @@ Array Object::_get_incoming_connections() const {
 	Array ret;
 	int connections_amount = connections.size();
 	for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) {
-		Dictionary conn_data;
-		conn_data["source"] = connections[idx_conn].source;
-		conn_data["signal_name"] = connections[idx_conn].signal;
-		conn_data["method_name"] = connections[idx_conn].method;
-		ret.push_back(conn_data);
+		ret.push_back(connections[idx_conn]);
 	}
 
 	return ret;
@@ -1380,7 +1352,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
 
 	while ((S = signal_map.next(S))) {
 
-		const Signal *s = &signal_map[*S];
+		const SignalData *s = &signal_map[*S];
 
 		for (int i = 0; i < s->slot_map.size(); i++) {
 
@@ -1391,7 +1363,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
 
 void Object::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
 
-	const Signal *s = signal_map.getptr(p_signal);
+	const SignalData *s = signal_map.getptr(p_signal);
 	if (!s)
 		return; //nothing
 
@@ -1406,7 +1378,7 @@ int Object::get_persistent_signal_connection_count() const {
 
 	while ((S = signal_map.next(S))) {
 
-		const Signal *s = &signal_map[*S];
+		const SignalData *s = &signal_map[*S];
 
 		for (int i = 0; i < s->slot_map.size(); i++) {
 			if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
@@ -1425,11 +1397,15 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons
 	}
 }
 
-Error Object::connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+Error Object::connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+	return connect(p_signal, Callable(p_to_object, p_to_method), p_binds, p_flags);
+}
+Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
 
-	ERR_FAIL_NULL_V(p_to_object, ERR_INVALID_PARAMETER);
+	ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER);
 
-	Signal *s = signal_map.getptr(p_signal);
+	SignalData *s = signal_map.getptr(p_signal);
 	if (!s) {
 		bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
 		//check in script
@@ -1448,33 +1424,32 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
 #endif
 		}
 
-		ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'.");
+		ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to callable '" + p_callable + "'.");
 
-		signal_map[p_signal] = Signal();
+		signal_map[p_signal] = SignalData();
 		s = &signal_map[p_signal];
 	}
 
-	Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+	Callable target = p_callable;
+
 	if (s->slot_map.has(target)) {
 		if (p_flags & CONNECT_REFERENCE_COUNTED) {
 			s->slot_map[target].reference_count++;
 			return OK;
 		} else {
-			ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object.");
+			ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given callable '" + p_callable + "' in that object.");
 		}
 	}
 
-	Signal::Slot slot;
+	SignalData::Slot slot;
 
 	Connection conn;
-	conn.source = this;
-	conn.target = p_to_object;
-	conn.method = p_to_method;
-	conn.signal = p_signal;
+	conn.callable = target;
+	conn.signal = ::Signal(this, p_signal);
 	conn.flags = p_flags;
 	conn.binds = p_binds;
 	slot.conn = conn;
-	slot.cE = p_to_object->connections.push_back(conn);
+	slot.cE = p_callable.get_object()->connections.push_back(conn);
 	if (p_flags & CONNECT_REFERENCE_COUNTED) {
 		slot.reference_count = 1;
 	}
@@ -1484,10 +1459,15 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
 	return OK;
 }
 
-bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
+bool Object::is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
 
-	ERR_FAIL_NULL_V(p_to_object, false);
-	const Signal *s = signal_map.getptr(p_signal);
+	return is_connected(p_signal, Callable(p_to_object, p_to_method));
+}
+
+bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const {
+
+	ERR_FAIL_COND_V(p_callable.is_null(), false);
+	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)
@@ -1499,28 +1479,31 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const
 		ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
 	}
 
-	Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+	Callable target = p_callable;
 
 	return s->slot_map.has(target);
 	//const Map<Signal::Target,Signal::Slot>::Element *E = s->slot_map.find(target);
 	//return (E!=NULL);
 }
 
-void Object::disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
+void Object::disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
 
-	_disconnect(p_signal, p_to_object, p_to_method);
+	_disconnect(p_signal, Callable(p_to_object, p_to_method));
 }
-void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force) {
 
-	ERR_FAIL_NULL(p_to_object);
-	Signal *s = signal_map.getptr(p_signal);
-	ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
+void Object::disconnect(const StringName &p_signal, const Callable &p_callable) {
+	_disconnect(p_signal, p_callable);
+}
+
+void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) {
 
-	Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+	ERR_FAIL_COND(p_callable.is_null());
+	SignalData *s = signal_map.getptr(p_signal);
+	ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
 
-	ERR_FAIL_COND_MSG(!s->slot_map.has(target), "Disconnecting nonexistent signal '" + p_signal + "', slot: " + itos(target._id) + ":" + target.method + ".");
+	ERR_FAIL_COND_MSG(!s->slot_map.has(p_callable), "Disconnecting nonexistent signal '" + p_signal + "', callable: " + p_callable + ".");
 
-	Signal::Slot *slot = &s->slot_map[target];
+	SignalData::Slot *slot = &s->slot_map[p_callable];
 
 	if (!p_force) {
 		slot->reference_count--; // by default is zero, if it was not referenced it will go below it
@@ -1528,9 +1511,10 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
 			return;
 		}
 	}
-
-	p_to_object->connections.erase(slot->cE);
-	s->slot_map.erase(target);
+	Object *object = p_callable.get_object();
+	ERR_FAIL_COND(!object);
+	object->connections.erase(slot->cE);
+	s->slot_map.erase(p_callable);
 
 	if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(), p_signal)) {
 		//not user signal, delete
@@ -1710,9 +1694,9 @@ void Object::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list);
 	ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections);
 
-	ClassDB::bind_method(D_METHOD("connect", "signal", "target", "method", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0));
-	ClassDB::bind_method(D_METHOD("disconnect", "signal", "target", "method"), &Object::disconnect);
-	ClassDB::bind_method(D_METHOD("is_connected", "signal", "target", "method"), &Object::is_connected);
+	ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "binds", "flags"), &Object::connect, DEFVAL(Array()), 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("set_block_signals", "enable"), &Object::set_block_signals);
 	ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals);
@@ -1829,7 +1813,7 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
 		return Variant::NIL;
 	}
 
-	Variant::CallError ce;
+	Callable::CallError ce;
 	Variant check = Variant::construct(t, NULL, 0, ce);
 
 	for (int i = 1; i < p_path.size(); i++) {
@@ -1956,15 +1940,15 @@ Object::~Object() {
 
 	while ((S = signal_map.next(NULL))) {
 
-		Signal *s = &signal_map[*S];
+		SignalData *s = &signal_map[*S];
 
 		//brute force disconnect for performance
 		int slot_count = s->slot_map.size();
-		const VMap<Signal::Target, Signal::Slot>::Pair *slot_list = s->slot_map.get_array();
+		const VMap<Callable, SignalData::Slot>::Pair *slot_list = s->slot_map.get_array();
 
 		for (int i = 0; i < slot_count; i++) {
 
-			slot_list[i].value.conn.target->connections.erase(slot_list[i].value.cE);
+			slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
 		}
 
 		signal_map.erase(*S);
@@ -1974,7 +1958,7 @@ Object::~Object() {
 	while (connections.size()) {
 
 		Connection c = connections.front()->get();
-		c.source->_disconnect(c.signal, c.target, c.method, true);
+		c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
 	}
 
 	ObjectDB::remove_instance(this);

+ 19 - 32
core/object.h

@@ -413,18 +413,15 @@ public:
 
 	struct Connection {
 
-		Object *source;
-		StringName signal;
-		Object *target;
-		StringName method;
+		::Signal signal;
+		Callable callable;
+
 		uint32_t flags;
 		Vector<Variant> binds;
 		bool operator<(const Connection &p_conn) const;
 
 		operator Variant() const;
 		Connection() {
-			source = NULL;
-			target = NULL;
 			flags = 0;
 		}
 		Connection(const Variant &p_variant);
@@ -441,21 +438,7 @@ private:
 	friend bool predelete_handler(Object *);
 	friend void postinitialize_handler(Object *);
 
-	struct Signal {
-
-		struct Target {
-
-			ObjectID _id;
-			StringName method;
-
-			_FORCE_INLINE_ bool operator<(const Target &p_target) const { return (_id == p_target._id) ? (method < p_target.method) : (_id < p_target._id); }
-
-			Target(const ObjectID &p_id, const StringName &p_method) :
-					_id(p_id),
-					method(p_method) {
-			}
-			Target() { _id = ObjectID(); }
-		};
+	struct SignalData {
 
 		struct Slot {
 
@@ -466,11 +449,11 @@ private:
 		};
 
 		MethodInfo user;
-		VMap<Target, Slot> slot_map;
-		Signal() {}
+		VMap<Callable, Slot> slot_map;
+		SignalData() {}
 	};
 
-	HashMap<StringName, Signal> signal_map;
+	HashMap<StringName, SignalData> signal_map;
 	List<Connection> connections;
 #ifdef DEBUG_ENABLED
 	SafeRefCount _lock_index;
@@ -496,7 +479,7 @@ private:
 
 	void _add_user_signal(const String &p_name, const Array &p_args = Array());
 	bool _has_user_signal(const StringName &p_name) const;
-	Variant _emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+	Variant _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Array _get_signal_list() const;
 	Array _get_signal_connection_list(const String &p_signal) const;
 	Array _get_incoming_connections() const;
@@ -554,8 +537,8 @@ protected:
 	//Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
 	//void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
 
-	Variant _call_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
-	Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+	Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+	Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 
 	virtual const StringName *_get_class_namev() const {
 		if (!_class_name)
@@ -572,7 +555,7 @@ protected:
 	friend class ClassDB;
 	virtual void _validate_property(PropertyInfo &property) const;
 
-	void _disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force = false);
+	void _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
 
 public: //should be protected, but bug in clang++
 	static void initialize_class();
@@ -670,7 +653,7 @@ public:
 	bool has_method(const StringName &p_method) const;
 	void get_method_list(List<MethodInfo> *p_list) const;
 	Variant callv(const StringName &p_method, const Array &p_args);
-	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
 	virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
 	Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper
@@ -716,9 +699,13 @@ public:
 	int get_persistent_signal_connection_count() const;
 	void get_signals_connected_to_this(List<Connection> *p_connections) const;
 
-	Error connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
-	void disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method);
-	bool is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const;
+	Error connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+	void disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method);
+	bool is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const;
+
+	Error connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+	void disconnect(const StringName &p_signal, const Callable &p_callable);
+	bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
 
 	void call_deferred(const StringName &p_method, VARIANT_ARG_LIST);
 	void set_deferred(const StringName &p_property, const Variant &p_value);

+ 30 - 0
core/object_id.h

@@ -1,3 +1,33 @@
+/*************************************************************************/
+/*  object_id.h                                                          */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
 #ifndef OBJECT_ID_H
 #define OBJECT_ID_H
 

+ 3 - 0
core/register_core_types.cpp

@@ -99,6 +99,9 @@ extern void unregister_variant_methods();
 
 void register_core_types() {
 
+	//consistency check
+	ERR_FAIL_COND(sizeof(Callable) > 16);
+
 	ObjectDB::setup();
 	ResourceCache::setup();
 

+ 3 - 3
core/script_language.cpp

@@ -307,17 +307,17 @@ Variant ScriptInstance::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
 		argc++;
 	}
 
-	Variant::CallError error;
+	Callable::CallError error;
 	return call(p_method, argptr, argc, error);
 }
 
 void ScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
-	Variant::CallError ce;
+	Callable::CallError ce;
 	call(p_method, p_args, p_argcount, ce); // script may not support multilevel calls
 }
 
 void ScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
-	Variant::CallError ce;
+	Callable::CallError ce;
 	call(p_method, p_args, p_argcount, ce); // script may not support multilevel calls
 }
 

+ 4 - 4
core/script_language.h

@@ -197,7 +197,7 @@ public:
 	virtual void get_method_list(List<MethodInfo> *p_list) const = 0;
 	virtual bool has_method(const StringName &p_method) const = 0;
 	virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST);
-	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) = 0;
+	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0;
 	virtual void call_multilevel(const StringName &p_method, VARIANT_ARG_LIST);
 	virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
 	virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
@@ -424,12 +424,12 @@ public:
 	virtual void get_method_list(List<MethodInfo> *p_list) const;
 	virtual bool has_method(const StringName &p_method) const;
 	virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST) { return Variant(); }
-	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
 		return Variant();
 	}
 	//virtual void call_multilevel(const StringName& p_method,VARIANT_ARG_LIST) { return Variant(); }
-	//virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) { return Variant(); }
+	//virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount,Callable::CallError &r_error) { return Variant(); }
 	virtual void notification(int p_notification) {}
 
 	virtual Ref<Script> get_script() const { return script; }

+ 2 - 0
core/type_info.h

@@ -153,6 +153,8 @@ MAKE_TYPE_INFO(Transform, Variant::TRANSFORM)
 MAKE_TYPE_INFO(Color, Variant::COLOR)
 MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH)
 MAKE_TYPE_INFO(RID, Variant::_RID)
+MAKE_TYPE_INFO(Callable, Variant::CALLABLE)
+MAKE_TYPE_INFO(Signal, Variant::SIGNAL)
 MAKE_TYPE_INFO(Dictionary, Variant::DICTIONARY)
 MAKE_TYPE_INFO(Array, Variant::ARRAY)
 MAKE_TYPE_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)

+ 12 - 12
core/undo_redo.cpp

@@ -290,9 +290,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
 				}
 				argptrs.resize(argc);
 
-				Variant::CallError ce;
+				Callable::CallError ce;
 				obj->call(op.name, (const Variant **)argptrs.ptr(), argc, ce);
-				if (ce.error != Variant::CallError::CALL_OK) {
+				if (ce.error != Callable::CallError::CALL_OK) {
 					ERR_PRINT("Error calling method from signal '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, (const Variant **)argptrs.ptr(), argc, ce));
 				}
 #ifdef TOOLS_ENABLED
@@ -431,29 +431,29 @@ UndoRedo::~UndoRedo() {
 	clear_history();
 }
 
-Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	if (p_argcount < 2) {
-		r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 		r_error.argument = 0;
 		return Variant();
 	}
 
 	if (p_args[0]->get_type() != Variant::OBJECT) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 0;
 		r_error.expected = Variant::OBJECT;
 		return Variant();
 	}
 
 	if (p_args[1]->get_type() != Variant::STRING) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 1;
 		r_error.expected = Variant::STRING;
 		return Variant();
 	}
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 
 	Object *object = *p_args[0];
 	String method = *p_args[1];
@@ -469,29 +469,29 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Variant
 	return Variant();
 }
 
-Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	if (p_argcount < 2) {
-		r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 		r_error.argument = 0;
 		return Variant();
 	}
 
 	if (p_args[0]->get_type() != Variant::OBJECT) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 0;
 		r_error.expected = Variant::OBJECT;
 		return Variant();
 	}
 
 	if (p_args[1]->get_type() != Variant::STRING) {
-		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 		r_error.argument = 1;
 		r_error.expected = Variant::STRING;
 		return Variant();
 	}
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 
 	Object *object = *p_args[0];
 	String method = *p_args[1];

+ 2 - 2
core/undo_redo.h

@@ -47,8 +47,8 @@ public:
 	};
 
 	typedef void (*CommitNotifyCallback)(void *p_ud, const String &p_name);
-	Variant _add_do_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
-	Variant _add_undo_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+	Variant _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+	Variant _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 
 	typedef void (*MethodNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
 	typedef void (*PropertyNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);

+ 133 - 16
core/variant.cpp

@@ -128,6 +128,14 @@ String Variant::get_type_name(Variant::Type p_type) {
 
 			return "Object";
 		} break;
+		case CALLABLE: {
+
+			return "Callable";
+		} break;
+		case SIGNAL: {
+
+			return "Signal";
+		} break;
 		case NODE_PATH: {
 
 			return "NodePath";
@@ -792,6 +800,14 @@ bool Variant::is_zero() const {
 
 			return _get_obj().obj == NULL;
 		} break;
+		case CALLABLE: {
+
+			return reinterpret_cast<const Callable *>(_data._mem)->is_null();
+		} break;
+		case SIGNAL: {
+
+			return reinterpret_cast<const Signal *>(_data._mem)->is_null();
+		} break;
 		case NODE_PATH: {
 
 			return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
@@ -1022,6 +1038,14 @@ void Variant::reference(const Variant &p_variant) {
 			_get_obj().id = p_variant._get_obj().id;
 
 		} break;
+		case CALLABLE: {
+
+			memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem)));
+		} break;
+		case SIGNAL: {
+
+			memnew_placement(_data._mem, Signal(*reinterpret_cast<const Signal *>(p_variant._data._mem)));
+		} break;
 		case NODE_PATH: {
 
 			memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
@@ -1149,6 +1173,14 @@ void Variant::clear() {
 			// not much need probably
 			reinterpret_cast<RID *>(_data._mem)->~RID();
 		} break;
+		case CALLABLE: {
+
+			reinterpret_cast<Callable *>(_data._mem)->~Callable();
+		} break;
+		case SIGNAL: {
+
+			reinterpret_cast<Signal *>(_data._mem)->~Signal();
+		} break;
 		case DICTIONARY: {
 
 			reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary();
@@ -1627,6 +1659,18 @@ String Variant::stringify(List<const void *> &stack) const {
 				return "[Object:null]";
 
 		} break;
+		case CALLABLE: {
+			const Callable &c = *reinterpret_cast<const Callable *>(_data._mem);
+			return c;
+		} break;
+		case SIGNAL: {
+			const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
+			return s;
+		} break;
+		case _RID: {
+			const RID &s = *reinterpret_cast<const RID *>(_data._mem);
+			return "RID(" + itos(s.get_id()) + ")";
+		} break;
 		default: {
 			return "[" + get_type_name(type) + "]";
 		}
@@ -1776,9 +1820,9 @@ Variant::operator RID() const {
 			ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed).");
 		};
 #endif
-		Variant::CallError ce;
+		Callable::CallError ce;
 		Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, NULL, 0, ce);
-		if (ce.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::_RID) {
+		if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::_RID) {
 			return ret;
 		}
 		return RID();
@@ -1836,6 +1880,22 @@ Variant::operator Dictionary() const {
 		return Dictionary();
 }
 
+Variant::operator Callable() const {
+
+	if (type == CALLABLE)
+		return *reinterpret_cast<const Callable *>(_data._mem);
+	else
+		return Callable();
+}
+
+Variant::operator Signal() const {
+
+	if (type == SIGNAL)
+		return *reinterpret_cast<const Signal *>(_data._mem);
+	else
+		return Signal();
+}
+
 template <class DA, class SA>
 inline DA _convert_array(const SA &p_array) {
 
@@ -2243,6 +2303,17 @@ Variant::Variant(const Object *p_object) {
 	}
 }
 
+Variant::Variant(const Callable &p_callable) {
+
+	type = CALLABLE;
+	memnew_placement(_data._mem, Callable(p_callable));
+}
+Variant::Variant(const Signal &p_callable) {
+
+	type = SIGNAL;
+	memnew_placement(_data._mem, Signal(p_callable));
+}
+
 Variant::Variant(const Dictionary &p_dictionary) {
 
 	type = DICTIONARY;
@@ -2469,6 +2540,15 @@ void Variant::operator=(const Variant &p_variant) {
 			_get_obj().id = p_variant._get_obj().id;
 
 		} break;
+		case CALLABLE: {
+
+			*reinterpret_cast<Callable *>(_data._mem) = *reinterpret_cast<const Callable *>(p_variant._data._mem);
+		} break;
+		case SIGNAL: {
+
+			*reinterpret_cast<Signal *>(_data._mem) = *reinterpret_cast<const Signal *>(p_variant._data._mem);
+		} break;
+
 		case NODE_PATH: {
 
 			*reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem);
@@ -2676,6 +2756,17 @@ uint32_t Variant::hash() const {
 			return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
 
 		} break;
+		case CALLABLE: {
+
+			return reinterpret_cast<const Callable *>(_data._mem)->hash();
+
+		} break;
+		case SIGNAL: {
+
+			const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
+			uint32_t hash = s.get_name().hash();
+			return hash_djb2_one_64(s.get_object_id(), hash);
+		} break;
 		case ARRAY: {
 
 			const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
@@ -3054,24 +3145,24 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
 		argc++;
 	}
 
-	CallError error;
+	Callable::CallError error;
 
 	Variant ret = call(p_method, argptr, argc, error);
 
 	switch (error.error) {
 
-		case CallError::CALL_ERROR_INVALID_ARGUMENT: {
+		case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
 
-			String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(error.expected) + "'.";
+			String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'.";
 			ERR_PRINT(err.utf8().get_data());
 
 		} break;
-		case CallError::CALL_ERROR_INVALID_METHOD: {
+		case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
 
 			String err = "Invalid method '" + p_method + "' for type '" + Variant::get_type_name(type) + "'.";
 			ERR_PRINT(err.utf8().get_data());
 		} break;
-		case CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+		case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
 
 			String err = "Too many arguments for method '" + p_method + "'";
 			ERR_PRINT(err.utf8().get_data());
@@ -3096,26 +3187,26 @@ String Variant::get_construct_string() const {
 	return vars;
 }
 
-String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Variant::CallError &ce) {
+String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
 
 	String err_text;
 
-	if (ce.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+	if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
 		int errorarg = ce.argument;
 		if (p_argptrs) {
-			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(ce.expected) + ".";
+			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
 		} else {
-			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(ce.expected) + ".";
+			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
 		}
-	} else if (ce.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+	} else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
 		err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
-	} else if (ce.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+	} else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
 		err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
-	} else if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+	} else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
 		err_text = "Method not found.";
-	} else if (ce.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+	} else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
 		err_text = "Instance is null";
-	} else if (ce.error == Variant::CallError::CALL_OK) {
+	} else if (ce.error == Callable::CallError::CALL_OK) {
 		return "Call OK";
 	}
 
@@ -3128,6 +3219,32 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
 	return "'" + class_name + "::" + String(p_method) + "': " + err_text;
 }
 
+String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
+
+	String err_text;
+
+	if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+		int errorarg = ce.argument;
+		if (p_argptrs) {
+			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
+		} else {
+			err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
+		}
+	} else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+		err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
+	} else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+		err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
+	} else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
+		err_text = "Method not found.";
+	} else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+		err_text = "Instance is null";
+	} else if (ce.error == Callable::CallError::CALL_OK) {
+		return "Call OK";
+	}
+
+	return String(p_callable) + " : " + err_text;
+}
+
 String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
 
 	Array args;

+ 13 - 19
core/variant.h

@@ -32,6 +32,7 @@
 #define VARIANT_H
 
 #include "core/array.h"
+#include "core/callable.h"
 #include "core/color.h"
 #include "core/dictionary.h"
 #include "core/io/ip_address.h"
@@ -101,9 +102,10 @@ public:
 		NODE_PATH, // 15
 		_RID,
 		OBJECT,
+		CALLABLE,
+		SIGNAL,
 		DICTIONARY,
 		ARRAY,
-
 		// arrays
 		PACKED_BYTE_ARRAY, // 20
 		PACKED_INT_ARRAY,
@@ -202,6 +204,9 @@ public:
 	operator Node *() const;
 	operator Control *() const;
 
+	operator Callable() const;
+	operator Signal() const;
+
 	operator Dictionary() const;
 	operator Array() const;
 
@@ -262,6 +267,8 @@ public:
 	Variant(const NodePath &p_node_path);
 	Variant(const RID &p_rid);
 	Variant(const Object *p_object);
+	Variant(const Callable &p_callable);
+	Variant(const Signal &p_signal);
 	Variant(const Dictionary &p_dictionary);
 
 	Variant(const Array &p_array);
@@ -333,27 +340,14 @@ public:
 	static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
 	static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
 
-	struct CallError {
-		enum Error {
-			CALL_OK,
-			CALL_ERROR_INVALID_METHOD,
-			CALL_ERROR_INVALID_ARGUMENT,
-			CALL_ERROR_TOO_MANY_ARGUMENTS,
-			CALL_ERROR_TOO_FEW_ARGUMENTS,
-			CALL_ERROR_INSTANCE_IS_NULL,
-		};
-		Error error;
-		int argument;
-		Type expected;
-	};
-
-	void call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, CallError &r_error);
-	Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, CallError &r_error);
+	void call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error);
+	Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
 	Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant());
 
-	static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Variant::CallError &ce);
+	static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
+	static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
 
-	static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, CallError &r_error, bool p_strict = true);
+	static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict = true);
 
 	void get_method_list(List<MethodInfo> *p_list) const;
 	bool has_method(const StringName &p_method) const;

+ 124 - 23
core/variant_call.cpp

@@ -61,7 +61,7 @@ struct _VariantCall {
 
 		VariantFunc func;
 
-		_FORCE_INLINE_ bool verify_arguments(const Variant **p_args, Variant::CallError &r_error) {
+		_FORCE_INLINE_ bool verify_arguments(const Variant **p_args, Callable::CallError &r_error) {
 
 			if (arg_count == 0)
 				return true;
@@ -73,7 +73,7 @@ struct _VariantCall {
 				if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type)
 					continue; // all good
 				if (!Variant::can_convert(p_args[i]->type, tptr[i])) {
-					r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+					r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
 					r_error.argument = i;
 					r_error.expected = tptr[i];
 					return false;
@@ -82,10 +82,10 @@ struct _VariantCall {
 			return true;
 		}
 
-		_FORCE_INLINE_ void call(Variant &r_ret, Variant &p_self, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+		_FORCE_INLINE_ void call(Variant &r_ret, Variant &p_self, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 #ifdef DEBUG_ENABLED
 			if (p_argcount > arg_count) {
-				r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+				r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
 				r_error.argument = arg_count;
 				return;
 			} else
@@ -94,7 +94,7 @@ struct _VariantCall {
 				int def_argcount = default_args.size();
 #ifdef DEBUG_ENABLED
 				if (p_argcount < (arg_count - def_argcount)) {
-					r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+					r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
 					r_error.argument = arg_count - def_argcount;
 					return;
 				}
@@ -519,6 +519,23 @@ struct _VariantCall {
 	VCALL_LOCALMEM1R(Dictionary, duplicate);
 	VCALL_LOCALMEM2R(Dictionary, get);
 
+	VCALL_LOCALMEM0R(Callable, is_null);
+	VCALL_LOCALMEM0R(Callable, is_custom);
+	VCALL_LOCALMEM0(Callable, is_standard);
+	VCALL_LOCALMEM0(Callable, get_object);
+	VCALL_LOCALMEM0(Callable, get_object_id);
+	VCALL_LOCALMEM0(Callable, get_method);
+	VCALL_LOCALMEM0(Callable, hash);
+
+	VCALL_LOCALMEM0R(Signal, is_null);
+	VCALL_LOCALMEM0R(Signal, get_object);
+	VCALL_LOCALMEM0R(Signal, get_object_id);
+	VCALL_LOCALMEM0R(Signal, get_name);
+	VCALL_LOCALMEM3R(Signal, connect);
+	VCALL_LOCALMEM1(Signal, disconnect);
+	VCALL_LOCALMEM1R(Signal, is_connected);
+	VCALL_LOCALMEM0R(Signal, get_connections);
+
 	VCALL_LOCALMEM2(Array, set);
 	VCALL_LOCALMEM1R(Array, get);
 	VCALL_LOCALMEM0R(Array, size);
@@ -1010,6 +1027,16 @@ struct _VariantCall {
 		r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3());
 	}
 
+	static void Callable_init2(Variant &r_ret, const Variant **p_args) {
+
+		r_ret = Callable(p_args[0]->operator ObjectID(), p_args[1]->operator String());
+	}
+
+	static void Signal_init2(Variant &r_ret, const Variant **p_args) {
+
+		r_ret = Signal(p_args[0]->operator ObjectID(), p_args[1]->operator String());
+	}
+
 	static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type,
 			const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL,
 			const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL,
@@ -1078,26 +1105,26 @@ _VariantCall::TypeFunc *_VariantCall::type_funcs = NULL;
 _VariantCall::ConstructFunc *_VariantCall::construct_funcs = NULL;
 _VariantCall::ConstantData *_VariantCall::constant_data = NULL;
 
-Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, CallError &r_error) {
+Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 
 	Variant ret;
 	call_ptr(p_method, p_args, p_argcount, &ret, r_error);
 	return ret;
 }
 
-void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, CallError &r_error) {
+void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error) {
 	Variant ret;
 
 	if (type == Variant::OBJECT) {
 		//call object
 		Object *obj = _get_obj().obj;
 		if (!obj) {
-			r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+			r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
 			return;
 		}
 #ifdef DEBUG_ENABLED
 		if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
-			r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+			r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
 			return;
 		}
 
@@ -1108,31 +1135,57 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
 
 	} else {
 
-		r_error.error = Variant::CallError::CALL_OK;
+		r_error.error = Callable::CallError::CALL_OK;
 
 		Map<StringName, _VariantCall::FuncData>::Element *E = _VariantCall::type_funcs[type].functions.find(p_method);
-#ifdef DEBUG_ENABLED
-		if (!E) {
-			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
-			return;
+
+		if (E) {
+
+			_VariantCall::FuncData &funcdata = E->get();
+			funcdata.call(ret, *this, p_args, p_argcount, r_error);
+
+		} else {
+			//handle vararg functions manually
+			bool valid = false;
+			if (type == CALLABLE) {
+				if (p_method == CoreStringNames::get_singleton()->call) {
+
+					reinterpret_cast<const Callable *>(_data._mem)->call(p_args, p_argcount, ret, r_error);
+					valid = true;
+				}
+				if (p_method == CoreStringNames::get_singleton()->call_deferred) {
+					reinterpret_cast<const Callable *>(_data._mem)->call_deferred(p_args, p_argcount);
+					valid = true;
+				}
+			} else if (type == SIGNAL) {
+				if (p_method == CoreStringNames::get_singleton()->emit) {
+					if (r_ret) {
+						*r_ret = Variant();
+					}
+					reinterpret_cast<const Signal *>(_data._mem)->emit(p_args, p_argcount);
+					valid = true;
+				}
+			}
+			if (!valid) {
+				//ok fail because not found
+				r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+				return;
+			}
 		}
-#endif
-		_VariantCall::FuncData &funcdata = E->get();
-		funcdata.call(ret, *this, p_args, p_argcount, r_error);
 	}
 
-	if (r_error.error == Variant::CallError::CALL_OK && r_ret)
+	if (r_error.error == Callable::CallError::CALL_OK && r_ret)
 		*r_ret = ret;
 }
 
 #define VCALL(m_type, m_method) _VariantCall::_call_##m_type##_##m_method
 
-Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, CallError &r_error, bool p_strict) {
+Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict) {
 
-	r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+	r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
 	ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, Variant());
 
-	r_error.error = Variant::CallError::CALL_OK;
+	r_error.error = Callable::CallError::CALL_OK;
 	if (p_argcount == 0) { //generic construct
 
 		switch (p_type) {
@@ -1166,6 +1219,8 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 				return NodePath(); // 15
 			case _RID: return RID();
 			case OBJECT: return (Object *)NULL;
+			case CALLABLE: return Callable();
+			case SIGNAL: return Signal();
 			case DICTIONARY: return Dictionary();
 			case ARRAY:
 				return Array(); // 20
@@ -1249,7 +1304,7 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 			//validate parameters
 			for (int i = 0; i < cd.arg_count; i++) {
 				if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) {
-					r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
+					r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
 					r_error.argument = i;
 					r_error.expected = cd.arg_types[i];
 					return Variant();
@@ -1261,7 +1316,7 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
 			return v;
 		}
 	}
-	r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor
+	r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor
 	return Variant();
 }
 
@@ -1373,6 +1428,30 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
 
 		p_list->push_back(mi);
 	}
+
+	if (type == CALLABLE) {
+
+		MethodInfo mi;
+		mi.name = "call";
+		mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
+		mi.flags |= METHOD_FLAG_VARARG;
+
+		p_list->push_back(mi);
+
+		mi.name = "call_deferred";
+		mi.return_val.usage = 0;
+
+		p_list->push_back(mi);
+	}
+
+	if (type == SIGNAL) {
+
+		MethodInfo mi;
+		mi.name = "emit";
+		mi.flags |= METHOD_FLAG_VARARG;
+
+		p_list->push_back(mi);
+	}
 }
 
 void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list) {
@@ -1756,6 +1835,25 @@ void register_variant_methods() {
 	ADDFUNC1R(DICTIONARY, DICTIONARY, Dictionary, duplicate, BOOL, "deep", varray(false));
 	ADDFUNC2R(DICTIONARY, NIL, Dictionary, get, NIL, "key", NIL, "default", varray(Variant()));
 
+	ADDFUNC0R(CALLABLE, BOOL, Callable, is_null, varray());
+	ADDFUNC0R(CALLABLE, BOOL, Callable, is_custom, varray());
+	ADDFUNC0R(CALLABLE, BOOL, Callable, is_standard, varray());
+	ADDFUNC0R(CALLABLE, OBJECT, Callable, get_object, varray());
+	ADDFUNC0R(CALLABLE, INT, Callable, get_object_id, varray());
+	ADDFUNC0R(CALLABLE, STRING, Callable, get_method, varray());
+	ADDFUNC0R(CALLABLE, INT, Callable, hash, varray());
+
+	ADDFUNC0R(SIGNAL, BOOL, Signal, is_null, varray());
+	ADDFUNC0R(SIGNAL, OBJECT, Signal, get_object, varray());
+	ADDFUNC0R(SIGNAL, INT, Signal, get_object_id, varray());
+	ADDFUNC0R(SIGNAL, STRING, Signal, get_name, varray());
+
+	ADDFUNC3R(SIGNAL, INT, Signal, connect, CALLABLE, "callable", ARRAY, "binds", INT, "flags", varray(Array(), 0));
+
+	ADDFUNC1R(SIGNAL, NIL, Signal, disconnect, CALLABLE, "callable", varray());
+	ADDFUNC1R(SIGNAL, BOOL, Signal, is_connected, CALLABLE, "callable", varray());
+	ADDFUNC0R(SIGNAL, ARRAY, Signal, get_connections, varray());
+
 	ADDFUNC0R(ARRAY, INT, Array, size, varray());
 	ADDFUNC0R(ARRAY, BOOL, Array, empty, varray());
 	ADDFUNC0NC(ARRAY, NIL, Array, clear, varray());
@@ -1972,6 +2070,9 @@ void register_variant_methods() {
 	_VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3);
 	_VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3);
 
+	_VariantCall::add_constructor(_VariantCall::Callable_init2, Variant::CALLABLE, "object", Variant::OBJECT, "method_name", Variant::STRING);
+	_VariantCall::add_constructor(_VariantCall::Signal_init2, Variant::SIGNAL, "object", Variant::OBJECT, "signal_name", Variant::STRING);
+
 	/* REGISTER CONSTANTS */
 
 	_populate_named_colors();

+ 78 - 35
core/variant_op.cpp

@@ -56,6 +56,8 @@
 	CASE_TYPE(PREFIX, OP, NODE_PATH)            \
 	CASE_TYPE(PREFIX, OP, _RID)                 \
 	CASE_TYPE(PREFIX, OP, OBJECT)               \
+	CASE_TYPE(PREFIX, OP, CALLABLE)             \
+	CASE_TYPE(PREFIX, OP, SIGNAL)               \
 	CASE_TYPE(PREFIX, OP, DICTIONARY)           \
 	CASE_TYPE(PREFIX, OP, ARRAY)                \
 	CASE_TYPE(PREFIX, OP, PACKED_BYTE_ARRAY)    \
@@ -89,6 +91,8 @@
 		TYPE(PREFIX, OP, NODE_PATH),          \
 		TYPE(PREFIX, OP, _RID),               \
 		TYPE(PREFIX, OP, OBJECT),             \
+		TYPE(PREFIX, OP, CALLABLE),             \
+		TYPE(PREFIX, OP, SIGNAL),             \
 		TYPE(PREFIX, OP, DICTIONARY),         \
 		TYPE(PREFIX, OP, ARRAY),              \
 		TYPE(PREFIX, OP, PACKED_BYTE_ARRAY),    \
@@ -101,32 +105,32 @@
 }
 /* clang-format on */
 
-#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][27] = { \
-	TYPES(PREFIX, OP_EQUAL),                                               \
-	TYPES(PREFIX, OP_NOT_EQUAL),                                           \
-	TYPES(PREFIX, OP_LESS),                                                \
-	TYPES(PREFIX, OP_LESS_EQUAL),                                          \
-	TYPES(PREFIX, OP_GREATER),                                             \
-	TYPES(PREFIX, OP_GREATER_EQUAL),                                       \
-	TYPES(PREFIX, OP_ADD),                                                 \
-	TYPES(PREFIX, OP_SUBTRACT),                                            \
-	TYPES(PREFIX, OP_MULTIPLY),                                            \
-	TYPES(PREFIX, OP_DIVIDE),                                              \
-	TYPES(PREFIX, OP_NEGATE),                                              \
-	TYPES(PREFIX, OP_POSITIVE),                                            \
-	TYPES(PREFIX, OP_MODULE),                                              \
-	TYPES(PREFIX, OP_STRING_CONCAT),                                       \
-	TYPES(PREFIX, OP_SHIFT_LEFT),                                          \
-	TYPES(PREFIX, OP_SHIFT_RIGHT),                                         \
-	TYPES(PREFIX, OP_BIT_AND),                                             \
-	TYPES(PREFIX, OP_BIT_OR),                                              \
-	TYPES(PREFIX, OP_BIT_XOR),                                             \
-	TYPES(PREFIX, OP_BIT_NEGATE),                                          \
-	TYPES(PREFIX, OP_AND),                                                 \
-	TYPES(PREFIX, OP_OR),                                                  \
-	TYPES(PREFIX, OP_XOR),                                                 \
-	TYPES(PREFIX, OP_NOT),                                                 \
-	TYPES(PREFIX, OP_IN),                                                  \
+#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][Variant::VARIANT_MAX] = { \
+	TYPES(PREFIX, OP_EQUAL),                                                                 \
+	TYPES(PREFIX, OP_NOT_EQUAL),                                                             \
+	TYPES(PREFIX, OP_LESS),                                                                  \
+	TYPES(PREFIX, OP_LESS_EQUAL),                                                            \
+	TYPES(PREFIX, OP_GREATER),                                                               \
+	TYPES(PREFIX, OP_GREATER_EQUAL),                                                         \
+	TYPES(PREFIX, OP_ADD),                                                                   \
+	TYPES(PREFIX, OP_SUBTRACT),                                                              \
+	TYPES(PREFIX, OP_MULTIPLY),                                                              \
+	TYPES(PREFIX, OP_DIVIDE),                                                                \
+	TYPES(PREFIX, OP_NEGATE),                                                                \
+	TYPES(PREFIX, OP_POSITIVE),                                                              \
+	TYPES(PREFIX, OP_MODULE),                                                                \
+	TYPES(PREFIX, OP_STRING_CONCAT),                                                         \
+	TYPES(PREFIX, OP_SHIFT_LEFT),                                                            \
+	TYPES(PREFIX, OP_SHIFT_RIGHT),                                                           \
+	TYPES(PREFIX, OP_BIT_AND),                                                               \
+	TYPES(PREFIX, OP_BIT_OR),                                                                \
+	TYPES(PREFIX, OP_BIT_XOR),                                                               \
+	TYPES(PREFIX, OP_BIT_NEGATE),                                                            \
+	TYPES(PREFIX, OP_AND),                                                                   \
+	TYPES(PREFIX, OP_OR),                                                                    \
+	TYPES(PREFIX, OP_XOR),                                                                   \
+	TYPES(PREFIX, OP_NOT),                                                                   \
+	TYPES(PREFIX, OP_IN),                                                                    \
 }
 
 #define SWITCH(PREFIX, op, val) goto *switch_table_##PREFIX[op][val];
@@ -423,6 +427,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 				_RETURN_FAIL;
 			}
 
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, CALLABLE, ==, Callable);
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, SIGNAL, ==, Signal);
+
 			CASE_TYPE(math, OP_EQUAL, DICTIONARY) {
 				if (p_b.type != DICTIONARY) {
 					if (p_b.type == NIL)
@@ -511,6 +518,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 				_RETURN_FAIL;
 			}
 
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, CALLABLE, !=, Callable);
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, SIGNAL, !=, Signal);
+
 			CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) {
 				if (p_b.type != DICTIONARY) {
 					if (p_b.type == NIL)
@@ -592,6 +602,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 				_RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
 			}
 
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, CALLABLE, <, Callable);
+			DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, SIGNAL, <, Signal);
+
 			CASE_TYPE(math, OP_LESS, ARRAY) {
 				if (p_b.type != ARRAY)
 					_RETURN_FAIL;
@@ -664,6 +677,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM)
 			CASE_TYPE(math, OP_LESS_EQUAL, COLOR)
 			CASE_TYPE(math, OP_LESS_EQUAL, NODE_PATH)
+			CASE_TYPE(math, OP_LESS_EQUAL, CALLABLE)
+			CASE_TYPE(math, OP_LESS_EQUAL, SIGNAL)
+
 			CASE_TYPE(math, OP_LESS_EQUAL, DICTIONARY)
 			CASE_TYPE(math, OP_LESS_EQUAL, ARRAY)
 			CASE_TYPE(math, OP_LESS_EQUAL, PACKED_BYTE_ARRAY);
@@ -740,6 +756,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_GREATER, COLOR)
 			CASE_TYPE(math, OP_GREATER, NODE_PATH)
 			CASE_TYPE(math, OP_GREATER, DICTIONARY)
+			CASE_TYPE(math, OP_GREATER, CALLABLE)
+			CASE_TYPE(math, OP_GREATER, SIGNAL)
+
 			_RETURN_FAIL;
 		}
 
@@ -768,6 +787,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM)
 			CASE_TYPE(math, OP_GREATER_EQUAL, COLOR)
 			CASE_TYPE(math, OP_GREATER_EQUAL, NODE_PATH)
+			CASE_TYPE(math, OP_GREATER_EQUAL, CALLABLE)
+			CASE_TYPE(math, OP_GREATER_EQUAL, SIGNAL)
+
 			CASE_TYPE(math, OP_GREATER_EQUAL, DICTIONARY)
 			CASE_TYPE(math, OP_GREATER_EQUAL, ARRAY)
 			CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_BYTE_ARRAY);
@@ -825,6 +847,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_ADD, NODE_PATH)
 			CASE_TYPE(math, OP_ADD, _RID)
 			CASE_TYPE(math, OP_ADD, OBJECT)
+			CASE_TYPE(math, OP_ADD, CALLABLE)
+			CASE_TYPE(math, OP_ADD, SIGNAL)
+
 			CASE_TYPE(math, OP_ADD, DICTIONARY)
 			_RETURN_FAIL;
 		}
@@ -849,6 +874,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_SUBTRACT, NODE_PATH)
 			CASE_TYPE(math, OP_SUBTRACT, _RID)
 			CASE_TYPE(math, OP_SUBTRACT, OBJECT)
+			CASE_TYPE(math, OP_SUBTRACT, CALLABLE)
+			CASE_TYPE(math, OP_SUBTRACT, SIGNAL)
+
 			CASE_TYPE(math, OP_SUBTRACT, DICTIONARY)
 			CASE_TYPE(math, OP_SUBTRACT, ARRAY)
 			CASE_TYPE(math, OP_SUBTRACT, PACKED_BYTE_ARRAY);
@@ -928,6 +956,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_MULTIPLY, NODE_PATH)
 			CASE_TYPE(math, OP_MULTIPLY, _RID)
 			CASE_TYPE(math, OP_MULTIPLY, OBJECT)
+			CASE_TYPE(math, OP_MULTIPLY, CALLABLE)
+			CASE_TYPE(math, OP_MULTIPLY, SIGNAL)
+
 			CASE_TYPE(math, OP_MULTIPLY, DICTIONARY)
 			CASE_TYPE(math, OP_MULTIPLY, ARRAY)
 			CASE_TYPE(math, OP_MULTIPLY, PACKED_BYTE_ARRAY);
@@ -971,6 +1002,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_DIVIDE, NODE_PATH)
 			CASE_TYPE(math, OP_DIVIDE, _RID)
 			CASE_TYPE(math, OP_DIVIDE, OBJECT)
+			CASE_TYPE(math, OP_DIVIDE, CALLABLE)
+			CASE_TYPE(math, OP_DIVIDE, SIGNAL)
+
 			CASE_TYPE(math, OP_DIVIDE, DICTIONARY)
 			CASE_TYPE(math, OP_DIVIDE, ARRAY)
 			CASE_TYPE(math, OP_DIVIDE, PACKED_BYTE_ARRAY);
@@ -1003,6 +1037,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_POSITIVE, NODE_PATH)
 			CASE_TYPE(math, OP_POSITIVE, _RID)
 			CASE_TYPE(math, OP_POSITIVE, OBJECT)
+			CASE_TYPE(math, OP_POSITIVE, CALLABLE)
+			CASE_TYPE(math, OP_POSITIVE, SIGNAL)
+
 			CASE_TYPE(math, OP_POSITIVE, DICTIONARY)
 			CASE_TYPE(math, OP_POSITIVE, ARRAY)
 			CASE_TYPE(math, OP_POSITIVE, PACKED_BYTE_ARRAY)
@@ -1036,6 +1073,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_NEGATE, NODE_PATH)
 			CASE_TYPE(math, OP_NEGATE, _RID)
 			CASE_TYPE(math, OP_NEGATE, OBJECT)
+			CASE_TYPE(math, OP_NEGATE, CALLABLE)
+			CASE_TYPE(math, OP_NEGATE, SIGNAL)
+
 			CASE_TYPE(math, OP_NEGATE, DICTIONARY)
 			CASE_TYPE(math, OP_NEGATE, ARRAY)
 			CASE_TYPE(math, OP_NEGATE, PACKED_BYTE_ARRAY)
@@ -1096,6 +1136,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
 			CASE_TYPE(math, OP_MODULE, NODE_PATH)
 			CASE_TYPE(math, OP_MODULE, _RID)
 			CASE_TYPE(math, OP_MODULE, OBJECT)
+			CASE_TYPE(math, OP_MODULE, CALLABLE)
+			CASE_TYPE(math, OP_MODULE, SIGNAL)
+
 			CASE_TYPE(math, OP_MODULE, DICTIONARY)
 			CASE_TYPE(math, OP_MODULE, ARRAY)
 			CASE_TYPE(math, OP_MODULE, PACKED_BYTE_ARRAY)
@@ -2968,15 +3011,15 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
 			}
 
 #endif
-			Variant::CallError ce;
-			ce.error = Variant::CallError::CALL_OK;
+			Callable::CallError ce;
+			ce.error = Callable::CallError::CALL_OK;
 			Array ref;
 			ref.push_back(r_iter);
 			Variant vref = ref;
 			const Variant *refp[] = { &vref };
 			Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
 
-			if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
+			if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
 				valid = false;
 				return false;
 			}
@@ -3138,15 +3181,15 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
 			}
 
 #endif
-			Variant::CallError ce;
-			ce.error = Variant::CallError::CALL_OK;
+			Callable::CallError ce;
+			ce.error = Callable::CallError::CALL_OK;
 			Array ref;
 			ref.push_back(r_iter);
 			Variant vref = ref;
 			const Variant *refp[] = { &vref };
 			Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
 
-			if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
+			if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
 				valid = false;
 				return false;
 			}
@@ -3297,12 +3340,12 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
 			}
 
 #endif
-			Variant::CallError ce;
-			ce.error = Variant::CallError::CALL_OK;
+			Callable::CallError ce;
+			ce.error = Callable::CallError::CALL_OK;
 			const Variant *refp[] = { &r_iter };
 			Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
 
-			if (ce.error != Variant::CallError::CALL_OK) {
+			if (ce.error != Callable::CallError::CALL_OK) {
 				r_valid = false;
 				return Variant();
 			}

+ 10 - 10
editor/animation_bezier_editor.cpp

@@ -502,12 +502,12 @@ void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_a
 
 	animation = p_animation;
 	track = p_track;
-	if (is_connected("select_key", editor, "_key_selected"))
-		disconnect("select_key", editor, "_key_selected");
-	if (is_connected("deselect_key", editor, "_key_deselected"))
-		disconnect("deselect_key", editor, "_key_deselected");
-	connect("select_key", editor, "_key_selected", varray(p_track), CONNECT_DEFERRED);
-	connect("deselect_key", editor, "_key_deselected", varray(p_track), CONNECT_DEFERRED);
+	if (is_connected_compat("select_key", editor, "_key_selected"))
+		disconnect_compat("select_key", editor, "_key_selected");
+	if (is_connected_compat("deselect_key", editor, "_key_deselected"))
+		disconnect_compat("deselect_key", editor, "_key_deselected");
+	connect_compat("select_key", editor, "_key_selected", varray(p_track), CONNECT_DEFERRED);
+	connect_compat("deselect_key", editor, "_key_deselected", varray(p_track), CONNECT_DEFERRED);
 	update();
 }
 
@@ -522,11 +522,11 @@ void AnimationBezierTrackEdit::set_undo_redo(UndoRedo *p_undo_redo) {
 
 void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) {
 	timeline = p_timeline;
-	timeline->connect("zoom_changed", this, "_zoom_changed");
+	timeline->connect_compat("zoom_changed", this, "_zoom_changed");
 }
 void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) {
 	editor = p_editor;
-	connect("clear_selection", editor, "_clear_selection", varray(false));
+	connect_compat("clear_selection", editor, "_clear_selection", varray(false));
 }
 
 void AnimationBezierTrackEdit::_play_position_draw() {
@@ -1184,7 +1184,7 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() {
 	play_position->set_mouse_filter(MOUSE_FILTER_PASS);
 	add_child(play_position);
 	play_position->set_anchors_and_margins_preset(PRESET_WIDE);
-	play_position->connect("draw", this, "_play_position_draw");
+	play_position->connect_compat("draw", this, "_play_position_draw");
 	set_focus_mode(FOCUS_CLICK);
 
 	v_scroll = 0;
@@ -1198,7 +1198,7 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() {
 
 	menu = memnew(PopupMenu);
 	add_child(menu);
-	menu->connect("id_pressed", this, "_menu_selected");
+	menu->connect_compat("id_pressed", this, "_menu_selected");
 
 	//set_mouse_filter(MOUSE_FILTER_PASS); //scroll has to work too for selection
 }

+ 62 - 62
editor/animation_track_editor.cpp

@@ -235,7 +235,7 @@ public:
 						Variant::Type t = Variant::Type(int(p_value));
 
 						if (t != args[idx].get_type()) {
-							Variant::CallError err;
+							Callable::CallError err;
 							if (Variant::can_convert(args[idx].get_type(), t)) {
 								Variant old = args[idx];
 								Variant *ptrs[1] = { &old };
@@ -898,7 +898,7 @@ public:
 								Variant::Type t = Variant::Type(int(p_value));
 
 								if (t != args[idx].get_type()) {
-									Variant::CallError err;
+									Callable::CallError err;
 									if (Variant::can_convert(args[idx].get_type(), t)) {
 										Variant old = args[idx];
 										Variant *ptrs[1] = { &old };
@@ -1697,7 +1697,7 @@ void AnimationTimelineEdit::set_undo_redo(UndoRedo *p_undo_redo) {
 
 void AnimationTimelineEdit::set_zoom(Range *p_zoom) {
 	zoom = p_zoom;
-	zoom->connect("value_changed", this, "_zoom_changed");
+	zoom->connect_compat("value_changed", this, "_zoom_changed");
 }
 
 void AnimationTimelineEdit::set_play_position(float p_pos) {
@@ -1871,7 +1871,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
 	play_position->set_mouse_filter(MOUSE_FILTER_PASS);
 	add_child(play_position);
 	play_position->set_anchors_and_margins_preset(PRESET_WIDE);
-	play_position->connect("draw", this, "_play_position_draw");
+	play_position->connect_compat("draw", this, "_play_position_draw");
 
 	add_track = memnew(MenuButton);
 	add_track->set_position(Vector2(0, 0));
@@ -1895,17 +1895,17 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
 	length->set_custom_minimum_size(Vector2(70 * EDSCALE, 0));
 	length->set_hide_slider(true);
 	length->set_tooltip(TTR("Animation length (seconds)"));
-	length->connect("value_changed", this, "_anim_length_changed");
+	length->connect_compat("value_changed", this, "_anim_length_changed");
 	len_hb->add_child(length);
 	loop = memnew(ToolButton);
 	loop->set_tooltip(TTR("Animation Looping"));
-	loop->connect("pressed", this, "_anim_loop_pressed");
+	loop->connect_compat("pressed", this, "_anim_loop_pressed");
 	loop->set_toggle_mode(true);
 	len_hb->add_child(loop);
 	add_child(len_hb);
 
 	add_track->hide();
-	add_track->get_popup()->connect("index_pressed", this, "_track_added");
+	add_track->get_popup()->connect_compat("index_pressed", this, "_track_added");
 	len_hb->hide();
 
 	panning_timeline = false;
@@ -2429,8 +2429,8 @@ void AnimationTrackEdit::set_undo_redo(UndoRedo *p_undo_redo) {
 
 void AnimationTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) {
 	timeline = p_timeline;
-	timeline->connect("zoom_changed", this, "_zoom_changed");
-	timeline->connect("name_limit_changed", this, "_zoom_changed");
+	timeline->connect_compat("zoom_changed", this, "_zoom_changed");
+	timeline->connect_compat("name_limit_changed", this, "_zoom_changed");
 }
 void AnimationTrackEdit::set_editor(AnimationTrackEditor *p_editor) {
 	editor = p_editor;
@@ -2688,7 +2688,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
 			if (!menu) {
 				menu = memnew(PopupMenu);
 				add_child(menu);
-				menu->connect("id_pressed", this, "_menu_selected");
+				menu->connect_compat("id_pressed", this, "_menu_selected");
 			}
 			menu->clear();
 			menu->add_icon_item(get_icon("TrackContinuous", "EditorIcons"), TTR("Continuous"), MENU_CALL_MODE_CONTINUOUS);
@@ -2707,7 +2707,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
 			if (!menu) {
 				menu = memnew(PopupMenu);
 				add_child(menu);
-				menu->connect("id_pressed", this, "_menu_selected");
+				menu->connect_compat("id_pressed", this, "_menu_selected");
 			}
 			menu->clear();
 			menu->add_icon_item(get_icon("InterpRaw", "EditorIcons"), TTR("Nearest"), MENU_INTERPOLATION_NEAREST);
@@ -2725,7 +2725,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
 			if (!menu) {
 				menu = memnew(PopupMenu);
 				add_child(menu);
-				menu->connect("id_pressed", this, "_menu_selected");
+				menu->connect_compat("id_pressed", this, "_menu_selected");
 			}
 			menu->clear();
 			menu->add_icon_item(get_icon("InterpWrapClamp", "EditorIcons"), TTR("Clamp Loop Interp"), MENU_LOOP_CLAMP);
@@ -2820,7 +2820,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
 			if (!menu) {
 				menu = memnew(PopupMenu);
 				add_child(menu);
-				menu->connect("id_pressed", this, "_menu_selected");
+				menu->connect_compat("id_pressed", this, "_menu_selected");
 			}
 
 			menu->clear();
@@ -2848,7 +2848,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
 			path = memnew(LineEdit);
 			add_child(path);
 			path->set_as_toplevel(true);
-			path->connect("text_entered", this, "_path_entered");
+			path->connect_compat("text_entered", this, "_path_entered");
 		}
 
 		path->set_text(animation->track_get_path(track));
@@ -3111,7 +3111,7 @@ AnimationTrackEdit::AnimationTrackEdit() {
 	play_position->set_mouse_filter(MOUSE_FILTER_PASS);
 	add_child(play_position);
 	play_position->set_anchors_and_margins_preset(PRESET_WIDE);
-	play_position->connect("draw", this, "_play_position_draw");
+	play_position->connect_compat("draw", this, "_play_position_draw");
 	set_focus_mode(FOCUS_CLICK);
 	set_mouse_filter(MOUSE_FILTER_PASS); //scroll has to work too for selection
 }
@@ -3138,7 +3138,7 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_value_track_edit(Object *p_
 			&args[5]
 		};
 
-		Variant::CallError ce;
+		Callable::CallError ce;
 		return Object::cast_to<AnimationTrackEdit>(get_script_instance()->call("create_value_track_edit", (const Variant **)&argptrs, 6, ce).operator Object *());
 	}
 	return NULL;
@@ -3217,8 +3217,8 @@ Size2 AnimationTrackEditGroup::get_minimum_size() const {
 
 void AnimationTrackEditGroup::set_timeline(AnimationTimelineEdit *p_timeline) {
 	timeline = p_timeline;
-	timeline->connect("zoom_changed", this, "_zoom_changed");
-	timeline->connect("name_limit_changed", this, "_zoom_changed");
+	timeline->connect_compat("zoom_changed", this, "_zoom_changed");
+	timeline->connect_compat("name_limit_changed", this, "_zoom_changed");
 }
 
 void AnimationTrackEditGroup::set_root(Node *p_root) {
@@ -3258,7 +3258,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
 		track_edits[_get_track_selected()]->release_focus();
 	}
 	if (animation.is_valid()) {
-		animation->disconnect("changed", this, "_animation_changed");
+		animation->disconnect_compat("changed", this, "_animation_changed");
 		_clear_selection();
 	}
 	animation = p_anim;
@@ -3268,7 +3268,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
 	_update_tracks();
 
 	if (animation.is_valid()) {
-		animation->connect("changed", this, "_animation_changed");
+		animation->connect_compat("changed", this, "_animation_changed");
 
 		hscroll->show();
 		edit->set_disabled(false);
@@ -3311,13 +3311,13 @@ void AnimationTrackEditor::_root_removed(Node *p_root) {
 
 void AnimationTrackEditor::set_root(Node *p_root) {
 	if (root) {
-		root->disconnect("tree_exiting", this, "_root_removed");
+		root->disconnect_compat("tree_exiting", this, "_root_removed");
 	}
 
 	root = p_root;
 
 	if (root) {
-		root->connect("tree_exiting", this, "_root_removed", make_binds(), CONNECT_ONESHOT);
+		root->connect_compat("tree_exiting", this, "_root_removed", make_binds(), CONNECT_ONESHOT);
 	}
 
 	_update_tracks();
@@ -4257,21 +4257,21 @@ void AnimationTrackEditor::_update_tracks() {
 			track_edit->grab_focus();
 		}
 
-		track_edit->connect("timeline_changed", this, "_timeline_changed");
-		track_edit->connect("remove_request", this, "_track_remove_request", varray(), CONNECT_DEFERRED);
-		track_edit->connect("dropped", this, "_dropped_track", varray(), CONNECT_DEFERRED);
-		track_edit->connect("insert_key", this, "_insert_key_from_track", varray(i), CONNECT_DEFERRED);
-		track_edit->connect("select_key", this, "_key_selected", varray(i), CONNECT_DEFERRED);
-		track_edit->connect("deselect_key", this, "_key_deselected", varray(i), CONNECT_DEFERRED);
-		track_edit->connect("bezier_edit", this, "_bezier_edit", varray(i), CONNECT_DEFERRED);
-		track_edit->connect("move_selection_begin", this, "_move_selection_begin");
-		track_edit->connect("move_selection", this, "_move_selection");
-		track_edit->connect("move_selection_commit", this, "_move_selection_commit");
-		track_edit->connect("move_selection_cancel", this, "_move_selection_cancel");
+		track_edit->connect_compat("timeline_changed", this, "_timeline_changed");
+		track_edit->connect_compat("remove_request", this, "_track_remove_request", varray(), CONNECT_DEFERRED);
+		track_edit->connect_compat("dropped", this, "_dropped_track", varray(), CONNECT_DEFERRED);
+		track_edit->connect_compat("insert_key", this, "_insert_key_from_track", varray(i), CONNECT_DEFERRED);
+		track_edit->connect_compat("select_key", this, "_key_selected", varray(i), CONNECT_DEFERRED);
+		track_edit->connect_compat("deselect_key", this, "_key_deselected", varray(i), CONNECT_DEFERRED);
+		track_edit->connect_compat("bezier_edit", this, "_bezier_edit", varray(i), CONNECT_DEFERRED);
+		track_edit->connect_compat("move_selection_begin", this, "_move_selection_begin");
+		track_edit->connect_compat("move_selection", this, "_move_selection");
+		track_edit->connect_compat("move_selection_commit", this, "_move_selection_commit");
+		track_edit->connect_compat("move_selection_cancel", this, "_move_selection_cancel");
 
-		track_edit->connect("duplicate_request", this, "_edit_menu_pressed", varray(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED);
-		track_edit->connect("duplicate_transpose_request", this, "_edit_menu_pressed", varray(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED);
-		track_edit->connect("delete_request", this, "_edit_menu_pressed", varray(EDIT_DELETE_SELECTION), CONNECT_DEFERRED);
+		track_edit->connect_compat("duplicate_request", this, "_edit_menu_pressed", varray(EDIT_DUPLICATE_SELECTION), CONNECT_DEFERRED);
+		track_edit->connect_compat("duplicate_transpose_request", this, "_edit_menu_pressed", varray(EDIT_DUPLICATE_TRANSPOSED), CONNECT_DEFERRED);
+		track_edit->connect_compat("delete_request", this, "_edit_menu_pressed", varray(EDIT_DELETE_SELECTION), CONNECT_DEFERRED);
 	}
 }
 
@@ -4384,7 +4384,7 @@ void AnimationTrackEditor::_notification(int p_what) {
 	}
 
 	if (p_what == NOTIFICATION_READY) {
-		EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed");
+		EditorNode::get_singleton()->get_editor_selection()->connect_compat("selection_changed", this, "_selection_changed");
 	}
 
 	if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
@@ -4753,7 +4753,7 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) {
 					Variant arg = E->get().default_arguments[i - first_defarg];
 					params.push_back(arg);
 				} else {
-					Variant::CallError ce;
+					Callable::CallError ce;
 					Variant arg = Variant::construct(E->get().arguments[i].type, NULL, 0, ce);
 					params.push_back(arg);
 				}
@@ -5813,11 +5813,11 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	timeline = memnew(AnimationTimelineEdit);
 	timeline->set_undo_redo(undo_redo);
 	timeline_vbox->add_child(timeline);
-	timeline->connect("timeline_changed", this, "_timeline_changed");
-	timeline->connect("name_limit_changed", this, "_name_limit_changed");
-	timeline->connect("track_added", this, "_add_track");
-	timeline->connect("value_changed", this, "_timeline_value_changed");
-	timeline->connect("length_changed", this, "_update_length");
+	timeline->connect_compat("timeline_changed", this, "_timeline_changed");
+	timeline->connect_compat("name_limit_changed", this, "_name_limit_changed");
+	timeline->connect_compat("track_added", this, "_add_track");
+	timeline->connect_compat("value_changed", this, "_timeline_value_changed");
+	timeline->connect_compat("length_changed", this, "_update_length");
 
 	scroll = memnew(ScrollContainer);
 	timeline_vbox->add_child(scroll);
@@ -5825,7 +5825,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	VScrollBar *sb = scroll->get_v_scrollbar();
 	scroll->remove_child(sb);
 	timeline_scroll->add_child(sb); //move here so timeline and tracks are always aligned
-	scroll->connect("gui_input", this, "_scroll_input");
+	scroll->connect_compat("gui_input", this, "_scroll_input");
 
 	bezier_edit = memnew(AnimationBezierTrackEdit);
 	timeline_vbox->add_child(bezier_edit);
@@ -5834,14 +5834,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	bezier_edit->set_timeline(timeline);
 	bezier_edit->hide();
 	bezier_edit->set_v_size_flags(SIZE_EXPAND_FILL);
-	bezier_edit->connect("close_request", this, "_cancel_bezier_edit");
+	bezier_edit->connect_compat("close_request", this, "_cancel_bezier_edit");
 
 	timeline_vbox->set_custom_minimum_size(Size2(0, 150) * EDSCALE);
 
 	hscroll = memnew(HScrollBar);
 	hscroll->share(timeline);
 	hscroll->hide();
-	hscroll->connect("value_changed", this, "_update_scroll");
+	hscroll->connect_compat("value_changed", this, "_update_scroll");
 	timeline_vbox->add_child(hscroll);
 	timeline->set_hscroll(hscroll);
 
@@ -5858,20 +5858,20 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	imported_anim_warning = memnew(Button);
 	imported_anim_warning->hide();
 	imported_anim_warning->set_tooltip(TTR("Warning: Editing imported animation"));
-	imported_anim_warning->connect("pressed", this, "_show_imported_anim_warning");
+	imported_anim_warning->connect_compat("pressed", this, "_show_imported_anim_warning");
 	bottom_hb->add_child(imported_anim_warning);
 
 	bottom_hb->add_spacer();
 
 	selected_filter = memnew(ToolButton);
-	selected_filter->connect("pressed", this, "_view_group_toggle"); //same function works the same
+	selected_filter->connect_compat("pressed", this, "_view_group_toggle"); //same function works the same
 	selected_filter->set_toggle_mode(true);
 	selected_filter->set_tooltip(TTR("Only show tracks from nodes selected in tree."));
 
 	bottom_hb->add_child(selected_filter);
 
 	view_group = memnew(ToolButton);
-	view_group->connect("pressed", this, "_view_group_toggle");
+	view_group->connect_compat("pressed", this, "_view_group_toggle");
 	view_group->set_toggle_mode(true);
 	view_group->set_tooltip(TTR("Group tracks by node or display them as plain list."));
 
@@ -5893,14 +5893,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	step->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
 	step->set_tooltip(TTR("Animation step value."));
 	bottom_hb->add_child(step);
-	step->connect("value_changed", this, "_update_step");
+	step->connect_compat("value_changed", this, "_update_step");
 	step->set_read_only(true);
 
 	snap_mode = memnew(OptionButton);
 	snap_mode->add_item(TTR("Seconds"));
 	snap_mode->add_item(TTR("FPS"));
 	bottom_hb->add_child(snap_mode);
-	snap_mode->connect("item_selected", this, "_snap_mode_changed");
+	snap_mode->connect_compat("item_selected", this, "_snap_mode_changed");
 	snap_mode->set_disabled(true);
 
 	bottom_hb->add_child(memnew(VSeparator));
@@ -5945,19 +5945,19 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	edit->get_popup()->add_item(TTR("Optimize Animation"), EDIT_OPTIMIZE_ANIMATION);
 	edit->get_popup()->add_item(TTR("Clean-Up Animation"), EDIT_CLEAN_UP_ANIMATION);
 
-	edit->get_popup()->connect("id_pressed", this, "_edit_menu_pressed");
+	edit->get_popup()->connect_compat("id_pressed", this, "_edit_menu_pressed");
 
 	pick_track = memnew(SceneTreeDialog);
 	add_child(pick_track);
 	pick_track->set_title(TTR("Pick the node that will be animated:"));
-	pick_track->connect("selected", this, "_new_track_node_selected");
+	pick_track->connect_compat("selected", this, "_new_track_node_selected");
 	prop_selector = memnew(PropertySelector);
 	add_child(prop_selector);
-	prop_selector->connect("selected", this, "_new_track_property_selected");
+	prop_selector->connect_compat("selected", this, "_new_track_property_selected");
 
 	method_selector = memnew(PropertySelector);
 	add_child(method_selector);
-	method_selector->connect("selected", this, "_add_method_key");
+	method_selector->connect_compat("selected", this, "_add_method_key");
 
 	inserting = false;
 	insert_query = false;
@@ -5966,7 +5966,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 
 	insert_confirm = memnew(ConfirmationDialog);
 	add_child(insert_confirm);
-	insert_confirm->connect("confirmed", this, "_confirm_insert_list");
+	insert_confirm->connect_compat("confirmed", this, "_confirm_insert_list");
 	VBoxContainer *icvb = memnew(VBoxContainer);
 	insert_confirm->add_child(icvb);
 	insert_confirm_text = memnew(Label);
@@ -5984,7 +5984,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	box_selection->set_as_toplevel(true);
 	box_selection->set_mouse_filter(MOUSE_FILTER_IGNORE);
 	box_selection->hide();
-	box_selection->connect("draw", this, "_box_selection_draw");
+	box_selection->connect_compat("draw", this, "_box_selection_draw");
 	box_selecting = false;
 
 	//default plugins
@@ -6022,7 +6022,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	optimize_max_angle->set_value(22);
 
 	optimize_dialog->get_ok()->set_text(TTR("Optimize"));
-	optimize_dialog->connect("confirmed", this, "_edit_menu_pressed", varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
+	optimize_dialog->connect_compat("confirmed", this, "_edit_menu_pressed", varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
 
 	//
 
@@ -6048,7 +6048,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	cleanup_dialog->set_title(TTR("Clean-Up Animation(s) (NO UNDO!)"));
 	cleanup_dialog->get_ok()->set_text(TTR("Clean-Up"));
 
-	cleanup_dialog->connect("confirmed", this, "_edit_menu_pressed", varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
+	cleanup_dialog->connect_compat("confirmed", this, "_edit_menu_pressed", varray(EDIT_CLEAN_UP_ANIMATION_CONFIRM));
 
 	//
 	scale_dialog = memnew(ConfirmationDialog);
@@ -6060,7 +6060,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	scale->set_max(99999);
 	scale->set_step(0.001);
 	vbc->add_margin_child(TTR("Scale Ratio:"), scale);
-	scale_dialog->connect("confirmed", this, "_edit_menu_pressed", varray(EDIT_SCALE_CONFIRM));
+	scale_dialog->connect_compat("confirmed", this, "_edit_menu_pressed", varray(EDIT_SCALE_CONFIRM));
 	add_child(scale_dialog);
 
 	track_copy_dialog = memnew(ConfirmationDialog);
@@ -6073,7 +6073,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 
 	Button *select_all_button = memnew(Button);
 	select_all_button->set_text(TTR("Select All/None"));
-	select_all_button->connect("pressed", this, "_select_all_tracks_for_copy");
+	select_all_button->connect_compat("pressed", this, "_select_all_tracks_for_copy");
 	track_vbox->add_child(select_all_button);
 
 	track_copy_select = memnew(Tree);
@@ -6081,7 +6081,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
 	track_copy_select->set_v_size_flags(SIZE_EXPAND_FILL);
 	track_copy_select->set_hide_root(true);
 	track_vbox->add_child(track_copy_select);
-	track_copy_dialog->connect("confirmed", this, "_edit_menu_pressed", varray(EDIT_COPY_TRACKS_CONFIRM));
+	track_copy_dialog->connect_compat("confirmed", this, "_edit_menu_pressed", varray(EDIT_COPY_TRACKS_CONFIRM));
 	animation_changing_awaiting_update = false;
 }
 

+ 2 - 2
editor/animation_track_editor_plugins.cpp

@@ -334,7 +334,7 @@ void AnimationTrackEditAudio::_bind_methods() {
 }
 
 AnimationTrackEditAudio::AnimationTrackEditAudio() {
-	AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed");
+	AudioStreamPreviewGenerator::get_singleton()->connect_compat("preview_updated", this, "_preview_changed");
 }
 
 /// SPRITE FRAME / FRAME_COORDS ///
@@ -949,7 +949,7 @@ void AnimationTrackEditTypeAudio::_bind_methods() {
 }
 
 AnimationTrackEditTypeAudio::AnimationTrackEditTypeAudio() {
-	AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed");
+	AudioStreamPreviewGenerator::get_singleton()->connect_compat("preview_updated", this, "_preview_changed");
 	len_resizing = false;
 }
 

+ 3 - 3
editor/array_property_edit.cpp

@@ -42,7 +42,7 @@ Variant ArrayPropertyEdit::get_array() const {
 		return Array();
 	Variant arr = o->get(property);
 	if (!arr.is_array()) {
-		Variant::CallError ce;
+		Callable::CallError ce;
 		arr = Variant::construct(default_type, NULL, 0, ce);
 	}
 	return arr;
@@ -104,7 +104,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
 			} else if (newsize > size) {
 
 				Variant init;
-				Variant::CallError ce;
+				Callable::CallError ce;
 				Variant::Type new_type = subtype;
 				if (new_type == Variant::NIL && size) {
 					new_type = arr.get(size - 1).get_type();
@@ -139,7 +139,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
 
 			Variant value = arr.get(idx);
 			if (value.get_type() != type && type >= 0 && type < Variant::VARIANT_MAX) {
-				Variant::CallError ce;
+				Callable::CallError ce;
 				Variant new_value = Variant::construct(Variant::Type(type), NULL, 0, ce);
 				UndoRedo *ur = EditorNode::get_undo_redo();
 

+ 27 - 27
editor/code_editor.cpp

@@ -200,7 +200,7 @@ void FindReplaceBar::_replace() {
 
 void FindReplaceBar::_replace_all() {
 
-	text_edit->disconnect("text_changed", this, "_editor_text_changed");
+	text_edit->disconnect_compat("text_changed", this, "_editor_text_changed");
 	// Line as x so it gets priority in comparison, column as y.
 	Point2i orig_cursor(text_edit->cursor_get_line(), text_edit->cursor_get_column());
 	Point2i prev_match = Point2(-1, -1);
@@ -280,7 +280,7 @@ void FindReplaceBar::_replace_all() {
 	matches_label->add_color_override("font_color", rc > 0 ? get_color("font_color", "Label") : get_color("error_color", "Editor"));
 	matches_label->set_text(vformat(TTR("%d replaced."), rc));
 
-	text_edit->call_deferred("connect", "text_changed", this, "_editor_text_changed");
+	text_edit->call_deferred("connect", "text_changed", Callable(this, "_editor_text_changed"));
 	results_count = -1;
 }
 
@@ -559,7 +559,7 @@ void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) {
 
 	results_count = -1;
 	text_edit = p_text_edit;
-	text_edit->connect("text_changed", this, "_editor_text_changed");
+	text_edit->connect_compat("text_changed", this, "_editor_text_changed");
 }
 
 void FindReplaceBar::_bind_methods() {
@@ -613,8 +613,8 @@ FindReplaceBar::FindReplaceBar() {
 	search_text = memnew(LineEdit);
 	vbc_lineedit->add_child(search_text);
 	search_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
-	search_text->connect("text_changed", this, "_search_text_changed");
-	search_text->connect("text_entered", this, "_search_text_entered");
+	search_text->connect_compat("text_changed", this, "_search_text_changed");
+	search_text->connect_compat("text_entered", this, "_search_text_entered");
 
 	matches_label = memnew(Label);
 	hbc_button_search->add_child(matches_label);
@@ -623,51 +623,51 @@ FindReplaceBar::FindReplaceBar() {
 	find_prev = memnew(ToolButton);
 	hbc_button_search->add_child(find_prev);
 	find_prev->set_focus_mode(FOCUS_NONE);
-	find_prev->connect("pressed", this, "_search_prev");
+	find_prev->connect_compat("pressed", this, "_search_prev");
 
 	find_next = memnew(ToolButton);
 	hbc_button_search->add_child(find_next);
 	find_next->set_focus_mode(FOCUS_NONE);
-	find_next->connect("pressed", this, "_search_next");
+	find_next->connect_compat("pressed", this, "_search_next");
 
 	case_sensitive = memnew(CheckBox);
 	hbc_option_search->add_child(case_sensitive);
 	case_sensitive->set_text(TTR("Match Case"));
 	case_sensitive->set_focus_mode(FOCUS_NONE);
-	case_sensitive->connect("toggled", this, "_search_options_changed");
+	case_sensitive->connect_compat("toggled", this, "_search_options_changed");
 
 	whole_words = memnew(CheckBox);
 	hbc_option_search->add_child(whole_words);
 	whole_words->set_text(TTR("Whole Words"));
 	whole_words->set_focus_mode(FOCUS_NONE);
-	whole_words->connect("toggled", this, "_search_options_changed");
+	whole_words->connect_compat("toggled", this, "_search_options_changed");
 
 	// replace toolbar
 	replace_text = memnew(LineEdit);
 	vbc_lineedit->add_child(replace_text);
 	replace_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
-	replace_text->connect("text_entered", this, "_replace_text_entered");
+	replace_text->connect_compat("text_entered", this, "_replace_text_entered");
 
 	replace = memnew(Button);
 	hbc_button_replace->add_child(replace);
 	replace->set_text(TTR("Replace"));
-	replace->connect("pressed", this, "_replace_pressed");
+	replace->connect_compat("pressed", this, "_replace_pressed");
 
 	replace_all = memnew(Button);
 	hbc_button_replace->add_child(replace_all);
 	replace_all->set_text(TTR("Replace All"));
-	replace_all->connect("pressed", this, "_replace_all_pressed");
+	replace_all->connect_compat("pressed", this, "_replace_all_pressed");
 
 	selection_only = memnew(CheckBox);
 	hbc_option_replace->add_child(selection_only);
 	selection_only->set_text(TTR("Selection Only"));
 	selection_only->set_focus_mode(FOCUS_NONE);
-	selection_only->connect("toggled", this, "_search_options_changed");
+	selection_only->connect_compat("toggled", this, "_search_options_changed");
 
 	hide_button = memnew(TextureButton);
 	add_child(hide_button);
 	hide_button->set_focus_mode(FOCUS_NONE);
-	hide_button->connect("pressed", this, "_hide_pressed");
+	hide_button->connect_compat("pressed", this, "_hide_pressed");
 	hide_button->set_v_size_flags(SIZE_SHRINK_CENTER);
 }
 
@@ -1717,7 +1717,7 @@ CodeTextEditor::CodeTextEditor() {
 	error_column = 0;
 
 	toggle_scripts_button = memnew(ToolButton);
-	toggle_scripts_button->connect("pressed", this, "_toggle_scripts_pressed");
+	toggle_scripts_button->connect_compat("pressed", this, "_toggle_scripts_pressed");
 	status_bar->add_child(toggle_scripts_button);
 	toggle_scripts_button->hide();
 
@@ -1732,15 +1732,15 @@ CodeTextEditor::CodeTextEditor() {
 	scroll->add_child(error);
 	error->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
 	error->set_mouse_filter(MOUSE_FILTER_STOP);
-	error->connect("gui_input", this, "_error_pressed");
-	find_replace_bar->connect("error", error, "set_text");
+	error->connect_compat("gui_input", this, "_error_pressed");
+	find_replace_bar->connect_compat("error", error, "set_text");
 
 	// Warnings
 	warning_button = memnew(ToolButton);
 	status_bar->add_child(warning_button);
 	warning_button->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
 	warning_button->set_default_cursor_shape(CURSOR_POINTING_HAND);
-	warning_button->connect("pressed", this, "_warning_button_pressed");
+	warning_button->connect_compat("pressed", this, "_warning_button_pressed");
 	warning_button->set_tooltip(TTR("Warnings"));
 
 	warning_count_label = memnew(Label);
@@ -1752,7 +1752,7 @@ CodeTextEditor::CodeTextEditor() {
 	warning_count_label->set_tooltip(TTR("Warnings"));
 	warning_count_label->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("warning_color", "Editor"));
 	warning_count_label->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
-	warning_count_label->connect("gui_input", this, "_warning_label_gui_input");
+	warning_count_label->connect_compat("gui_input", this, "_warning_label_gui_input");
 
 	is_warnings_panel_opened = false;
 	set_warning_nb(0);
@@ -1765,10 +1765,10 @@ CodeTextEditor::CodeTextEditor() {
 	line_and_col_txt->set_tooltip(TTR("Line and column numbers."));
 	line_and_col_txt->set_mouse_filter(MOUSE_FILTER_STOP);
 
-	text_editor->connect("gui_input", this, "_text_editor_gui_input");
-	text_editor->connect("cursor_changed", this, "_line_col_changed");
-	text_editor->connect("text_changed", this, "_text_changed");
-	text_editor->connect("request_completion", this, "_complete_request");
+	text_editor->connect_compat("gui_input", this, "_text_editor_gui_input");
+	text_editor->connect_compat("cursor_changed", this, "_line_col_changed");
+	text_editor->connect_compat("text_changed", this, "_text_changed");
+	text_editor->connect_compat("request_completion", this, "_complete_request");
 	Vector<String> cs;
 	cs.push_back(".");
 	cs.push_back(",");
@@ -1776,9 +1776,9 @@ CodeTextEditor::CodeTextEditor() {
 	cs.push_back("=");
 	cs.push_back("$");
 	text_editor->set_completion(true, cs);
-	idle->connect("timeout", this, "_text_changed_idle_timeout");
+	idle->connect_compat("timeout", this, "_text_changed_idle_timeout");
 
-	code_complete_timer->connect("timeout", this, "_code_complete_timer_timeout");
+	code_complete_timer->connect_compat("timeout", this, "_code_complete_timer_timeout");
 
 	font_resize_val = 0;
 	font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
@@ -1786,7 +1786,7 @@ CodeTextEditor::CodeTextEditor() {
 	add_child(font_resize_timer);
 	font_resize_timer->set_one_shot(true);
 	font_resize_timer->set_wait_time(0.07);
-	font_resize_timer->connect("timeout", this, "_font_resize_timeout");
+	font_resize_timer->connect_compat("timeout", this, "_font_resize_timeout");
 
-	EditorSettings::get_singleton()->connect("settings_changed", this, "_on_settings_change");
+	EditorSettings::get_singleton()->connect_compat("settings_changed", this, "_on_settings_change");
 }

+ 37 - 30
editor/connections_dialog.cpp

@@ -304,7 +304,7 @@ bool ConnectDialog::is_editing() const {
  * If creating a connection from scratch, sensible defaults are used.
  * If editing an existing connection, previous data is retained.
  */
-void ConnectDialog::init(Connection c, bool bEdit) {
+void ConnectDialog::init(ConnectionData c, bool bEdit) {
 
 	set_hide_on_ok(false);
 
@@ -389,8 +389,8 @@ ConnectDialog::ConnectDialog() {
 
 	tree = memnew(SceneTreeEditor(false));
 	tree->set_connecting_signal(true);
-	tree->get_scene_tree()->connect("item_activated", this, "_ok");
-	tree->connect("node_selected", this, "_tree_node_selected");
+	tree->get_scene_tree()->connect_compat("item_activated", this, "_ok");
+	tree->connect_compat("node_selected", this, "_tree_node_selected");
 	tree->set_connect_to_script_mode(true);
 
 	Node *mc = vbc_left->add_margin_child(TTR("Connect to Script:"), tree, true);
@@ -429,12 +429,12 @@ ConnectDialog::ConnectDialog() {
 	Button *add_bind = memnew(Button);
 	add_bind->set_text(TTR("Add"));
 	add_bind_hb->add_child(add_bind);
-	add_bind->connect("pressed", this, "_add_bind");
+	add_bind->connect_compat("pressed", this, "_add_bind");
 
 	Button *del_bind = memnew(Button);
 	del_bind->set_text(TTR("Remove"));
 	add_bind_hb->add_child(del_bind);
-	del_bind->connect("pressed", this, "_remove_bind");
+	del_bind->connect_compat("pressed", this, "_remove_bind");
 
 	vbc_right->add_margin_child(TTR("Add Extra Call Argument:"), add_bind_hb);
 
@@ -447,13 +447,13 @@ ConnectDialog::ConnectDialog() {
 
 	dst_method = memnew(LineEdit);
 	dst_method->set_h_size_flags(SIZE_EXPAND_FILL);
-	dst_method->connect("text_entered", this, "_builtin_text_entered");
+	dst_method->connect_compat("text_entered", this, "_builtin_text_entered");
 	dstm_hb->add_child(dst_method);
 
 	advanced = memnew(CheckButton);
 	dstm_hb->add_child(advanced);
 	advanced->set_text(TTR("Advanced"));
-	advanced->connect("pressed", this, "_advanced_pressed");
+	advanced->connect_compat("pressed", this, "_advanced_pressed");
 
 	// Add spacing so the tree and inspector are the same size.
 	Control *spacing = memnew(Control);
@@ -525,7 +525,7 @@ void ConnectionsDock::_make_or_edit_connection() {
 	Node *target = selectedNode->get_node(dst_path);
 	ERR_FAIL_COND(!target);
 
-	Connection cToMake;
+	ConnectDialog::ConnectionData cToMake;
 	cToMake.source = connect_dialog->get_source();
 	cToMake.target = target;
 	cToMake.signal = connect_dialog->get_signal_name();
@@ -585,7 +585,7 @@ void ConnectionsDock::_make_or_edit_connection() {
 /*
  * Creates single connection w/ undo-redo functionality.
  */
-void ConnectionsDock::_connect(Connection cToMake) {
+void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
 
 	Node *source = static_cast<Node *>(cToMake.source);
 	Node *target = static_cast<Node *>(cToMake.target);
@@ -595,8 +595,10 @@ void ConnectionsDock::_connect(Connection cToMake) {
 
 	undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(cToMake.signal), String(cToMake.method)));
 
-	undo_redo->add_do_method(source, "connect", cToMake.signal, target, cToMake.method, cToMake.binds, cToMake.flags);
-	undo_redo->add_undo_method(source, "disconnect", cToMake.signal, target, cToMake.method);
+	Callable c(target, cToMake.method);
+
+	undo_redo->add_do_method(source, "connect", cToMake.signal, c, cToMake.binds, cToMake.flags);
+	undo_redo->add_undo_method(source, "disconnect", cToMake.signal, c);
 	undo_redo->add_do_method(this, "update_tree");
 	undo_redo->add_undo_method(this, "update_tree");
 	undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); //to force redraw of scene tree
@@ -610,13 +612,15 @@ void ConnectionsDock::_connect(Connection cToMake) {
  */
 void ConnectionsDock::_disconnect(TreeItem &item) {
 
-	Connection c = item.get_metadata(0);
+	Connection cd = item.get_metadata(0);
+	ConnectDialog::ConnectionData c = cd;
+
 	ERR_FAIL_COND(c.source != selectedNode); // Shouldn't happen but... Bugcheck.
 
 	undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), c.signal, c.method));
 
-	undo_redo->add_do_method(selectedNode, "disconnect", c.signal, c.target, c.method);
-	undo_redo->add_undo_method(selectedNode, "connect", c.signal, c.target, c.method, c.binds, c.flags);
+	undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
+	undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
 	undo_redo->add_do_method(this, "update_tree");
 	undo_redo->add_undo_method(this, "update_tree");
 	undo_redo->add_do_method(EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor(), "update_tree"); // To force redraw of scene tree.
@@ -641,9 +645,10 @@ void ConnectionsDock::_disconnect_all() {
 	undo_redo->create_action(vformat(TTR("Disconnect all from signal: '%s'"), signalName));
 
 	while (child) {
-		Connection c = child->get_metadata(0);
-		undo_redo->add_do_method(selectedNode, "disconnect", c.signal, c.target, c.method);
-		undo_redo->add_undo_method(selectedNode, "connect", c.signal, c.target, c.method, c.binds, c.flags);
+		Connection cd = child->get_metadata(0);
+		ConnectDialog::ConnectionData c = cd;
+		undo_redo->add_do_method(selectedNode, "disconnect", c.signal, Callable(c.target, c.method));
+		undo_redo->add_undo_method(selectedNode, "connect", c.signal, Callable(c.target, c.method), c.binds, c.flags);
 		child = child->get_next();
 	}
 
@@ -720,7 +725,7 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
 
 	StringName dst_method = "_on_" + midname + "_" + signal;
 
-	Connection c;
+	ConnectDialog::ConnectionData c;
 	c.source = selectedNode;
 	c.signal = StringName(signalname);
 	c.target = dst_node;
@@ -733,7 +738,7 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
 /*
  * Open connection dialog with Connection data to EDIT an existing connection.
  */
-void ConnectionsDock::_open_connection_dialog(Connection cToEdit) {
+void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
 
 	Node *src = static_cast<Node *>(cToEdit.source);
 	Node *dst = static_cast<Node *>(cToEdit.target);
@@ -753,7 +758,8 @@ void ConnectionsDock::_go_to_script(TreeItem &item) {
 	if (_is_item_signal(item))
 		return;
 
-	Connection c = item.get_metadata(0);
+	Connection cd = item.get_metadata(0);
+	ConnectDialog::ConnectionData c = cd;
 	ERR_FAIL_COND(c.source != selectedNode); //shouldn't happen but...bugcheck
 
 	if (!c.target)
@@ -1014,7 +1020,7 @@ void ConnectionsDock::update_tree() {
 
 			for (List<Object::Connection>::Element *F = connections.front(); F; F = F->next()) {
 
-				Object::Connection &c = F->get();
+				ConnectDialog::ConnectionData c = F->get();
 				if (!(c.flags & CONNECT_PERSIST))
 					continue;
 
@@ -1041,7 +1047,8 @@ void ConnectionsDock::update_tree() {
 
 				TreeItem *item2 = tree->create_item(item);
 				item2->set_text(0, path);
-				item2->set_metadata(0, c);
+				Connection cd = c;
+				item2->set_metadata(0, cd);
 				item2->set_icon(0, get_icon("Slot", "EditorIcons"));
 			}
 		}
@@ -1077,7 +1084,7 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) {
 	vbc->add_child(hb);
 	hb->add_spacer();
 	hb->add_child(connect_button);
-	connect_button->connect("pressed", this, "_connect_pressed");
+	connect_button->connect_compat("pressed", this, "_connect_pressed");
 
 	connect_dialog = memnew(ConnectDialog);
 	connect_dialog->set_as_toplevel(true);
@@ -1086,26 +1093,26 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) {
 	disconnect_all_dialog = memnew(ConfirmationDialog);
 	disconnect_all_dialog->set_as_toplevel(true);
 	add_child(disconnect_all_dialog);
-	disconnect_all_dialog->connect("confirmed", this, "_disconnect_all");
+	disconnect_all_dialog->connect_compat("confirmed", this, "_disconnect_all");
 	disconnect_all_dialog->set_text(TTR("Are you sure you want to remove all connections from this signal?"));
 
 	signal_menu = memnew(PopupMenu);
 	add_child(signal_menu);
-	signal_menu->connect("id_pressed", this, "_handle_signal_menu_option");
+	signal_menu->connect_compat("id_pressed", this, "_handle_signal_menu_option");
 	signal_menu->add_item(TTR("Connect..."), CONNECT);
 	signal_menu->add_item(TTR("Disconnect All"), DISCONNECT_ALL);
 
 	slot_menu = memnew(PopupMenu);
 	add_child(slot_menu);
-	slot_menu->connect("id_pressed", this, "_handle_slot_menu_option");
+	slot_menu->connect_compat("id_pressed", this, "_handle_slot_menu_option");
 	slot_menu->add_item(TTR("Edit..."), EDIT);
 	slot_menu->add_item(TTR("Go To Method"), GO_TO_SCRIPT);
 	slot_menu->add_item(TTR("Disconnect"), DISCONNECT);
 
-	connect_dialog->connect("connected", this, "_make_or_edit_connection");
-	tree->connect("item_selected", this, "_tree_item_selected");
-	tree->connect("item_activated", this, "_tree_item_activated");
-	tree->connect("item_rmb_selected", this, "_rmb_pressed");
+	connect_dialog->connect_compat("connected", this, "_make_or_edit_connection");
+	tree->connect_compat("item_selected", this, "_tree_item_selected");
+	tree->connect_compat("item_activated", this, "_tree_item_activated");
+	tree->connect_compat("item_rmb_selected", this, "_rmb_pressed");
 
 	add_constant_override("separation", 3 * EDSCALE);
 }

+ 33 - 3
editor/connections_dialog.h

@@ -53,6 +53,36 @@ class ConnectDialog : public ConfirmationDialog {
 
 	GDCLASS(ConnectDialog, ConfirmationDialog);
 
+public:
+	struct ConnectionData {
+		Node *source = nullptr;
+		Node *target = nullptr;
+		StringName signal;
+		StringName method;
+		uint32_t flags = 0;
+		Vector<Variant> binds;
+
+		ConnectionData() {
+		}
+		ConnectionData(const Connection &p_connection) {
+			source = Object::cast_to<Node>(p_connection.signal.get_object());
+			signal = p_connection.signal.get_name();
+			target = Object::cast_to<Node>(p_connection.callable.get_object());
+			method = p_connection.callable.get_method();
+			flags = p_connection.flags;
+			binds = p_connection.binds;
+		}
+		operator Connection() {
+			Connection c;
+			c.signal = ::Signal(source, signal);
+			c.callable = Callable(target, method);
+			c.flags = flags;
+			c.binds = binds;
+			return c;
+		}
+	};
+
+private:
 	Label *connect_to_label;
 	LineEdit *from_signal;
 	Node *source;
@@ -98,7 +128,7 @@ public:
 	bool get_oneshot() const;
 	bool is_editing() const;
 
-	void init(Connection c, bool bEdit = false);
+	void init(ConnectionData c, bool bEdit = false);
 
 	void popup_dialog(const String &p_for_signal);
 	ConnectDialog();
@@ -144,7 +174,7 @@ class ConnectionsDock : public VBoxContainer {
 	Map<StringName, Map<StringName, String> > descr_cache;
 
 	void _make_or_edit_connection();
-	void _connect(Connection cToMake);
+	void _connect(ConnectDialog::ConnectionData cToMake);
 	void _disconnect(TreeItem &item);
 	void _disconnect_all();
 
@@ -153,7 +183,7 @@ class ConnectionsDock : public VBoxContainer {
 	bool _is_item_signal(TreeItem &item);
 
 	void _open_connection_dialog(TreeItem &item);
-	void _open_connection_dialog(Connection cToEdit);
+	void _open_connection_dialog(ConnectDialog::ConnectionData cToEdit);
 	void _go_to_script(TreeItem &item);
 
 	void _handle_signal_menu_option(int option);

+ 12 - 12
editor/create_dialog.cpp

@@ -459,13 +459,13 @@ void CreateDialog::_notification(int p_what) {
 
 	switch (p_what) {
 		case NOTIFICATION_ENTER_TREE: {
-			connect("confirmed", this, "_confirmed");
+			connect_compat("confirmed", this, "_confirmed");
 			search_box->set_right_icon(get_icon("Search", "EditorIcons"));
 			search_box->set_clear_button_enabled(true);
 			favorite->set_icon(get_icon("Favorites", "EditorIcons"));
 		} break;
 		case NOTIFICATION_EXIT_TREE: {
-			disconnect("confirmed", this, "_confirmed");
+			disconnect_compat("confirmed", this, "_confirmed");
 		} break;
 		case NOTIFICATION_VISIBILITY_CHANGED: {
 			if (is_visible_in_tree()) {
@@ -766,8 +766,8 @@ CreateDialog::CreateDialog() {
 	favorites->set_hide_root(true);
 	favorites->set_hide_folding(true);
 	favorites->set_allow_reselect(true);
-	favorites->connect("cell_selected", this, "_favorite_selected");
-	favorites->connect("item_activated", this, "_favorite_activated");
+	favorites->connect_compat("cell_selected", this, "_favorite_selected");
+	favorites->connect_compat("item_activated", this, "_favorite_activated");
 	favorites->set_drag_forwarding(this);
 	favorites->add_constant_override("draw_guides", 1);
 
@@ -781,8 +781,8 @@ CreateDialog::CreateDialog() {
 	recent->set_hide_root(true);
 	recent->set_hide_folding(true);
 	recent->set_allow_reselect(true);
-	recent->connect("cell_selected", this, "_history_selected");
-	recent->connect("item_activated", this, "_history_activated");
+	recent->connect_compat("cell_selected", this, "_history_selected");
+	recent->connect_compat("item_activated", this, "_history_activated");
 	recent->add_constant_override("draw_guides", 1);
 
 	VBoxContainer *vbc = memnew(VBoxContainer);
@@ -797,23 +797,23 @@ CreateDialog::CreateDialog() {
 	favorite->set_flat(true);
 	favorite->set_toggle_mode(true);
 	search_hb->add_child(favorite);
-	favorite->connect("pressed", this, "_favorite_toggled");
+	favorite->connect_compat("pressed", this, "_favorite_toggled");
 	vbc->add_margin_child(TTR("Search:"), search_hb);
-	search_box->connect("text_changed", this, "_text_changed");
-	search_box->connect("gui_input", this, "_sbox_input");
+	search_box->connect_compat("text_changed", this, "_text_changed");
+	search_box->connect_compat("gui_input", this, "_sbox_input");
 	search_options = memnew(Tree);
 	vbc->add_margin_child(TTR("Matches:"), search_options, true);
 	get_ok()->set_disabled(true);
 	register_text_enter(search_box);
 	set_hide_on_ok(false);
-	search_options->connect("item_activated", this, "_confirmed");
-	search_options->connect("cell_selected", this, "_item_selected");
+	search_options->connect_compat("item_activated", this, "_confirmed");
+	search_options->connect_compat("cell_selected", this, "_item_selected");
 	base_type = "Object";
 	preferred_search_result_type = "";
 
 	help_bit = memnew(EditorHelpBit);
 	vbc->add_margin_child(TTR("Description:"), help_bit);
-	help_bit->connect("request_hide", this, "_closed");
+	help_bit->connect_compat("request_hide", this, "_closed");
 
 	type_blacklist.insert("PluginScript"); // PluginScript must be initialized before use, which is not possible here
 	type_blacklist.insert("ScriptCreateDialog"); // This is an exposed editor Node that doesn't have an Editor prefix.

+ 8 - 8
editor/dependency_editor.cpp

@@ -247,7 +247,7 @@ DependencyEditor::DependencyEditor() {
 	tree->set_column_title(0, TTR("Resource"));
 	tree->set_column_title(1, TTR("Path"));
 	tree->set_hide_root(true);
-	tree->connect("button_pressed", this, "_load_pressed");
+	tree->connect_compat("button_pressed", this, "_load_pressed");
 
 	HBoxContainer *hbc = memnew(HBoxContainer);
 	Label *label = memnew(Label(TTR("Dependencies:")));
@@ -255,7 +255,7 @@ DependencyEditor::DependencyEditor() {
 	hbc->add_spacer();
 	fixdeps = memnew(Button(TTR("Fix Broken")));
 	hbc->add_child(fixdeps);
-	fixdeps->connect("pressed", this, "_fix_all");
+	fixdeps->connect_compat("pressed", this, "_fix_all");
 
 	vb->add_child(hbc);
 
@@ -267,7 +267,7 @@ DependencyEditor::DependencyEditor() {
 
 	set_title(TTR("Dependency Editor"));
 	search = memnew(EditorFileDialog);
-	search->connect("file_selected", this, "_searched");
+	search->connect_compat("file_selected", this, "_searched");
 	search->set_mode(EditorFileDialog::MODE_OPEN_FILE);
 	search->set_title(TTR("Search Replacement Resource:"));
 	add_child(search);
@@ -360,12 +360,12 @@ DependencyEditorOwners::DependencyEditorOwners(EditorNode *p_editor) {
 
 	file_options = memnew(PopupMenu);
 	add_child(file_options);
-	file_options->connect("id_pressed", this, "_file_option");
+	file_options->connect_compat("id_pressed", this, "_file_option");
 
 	owners = memnew(ItemList);
 	owners->set_select_mode(ItemList::SELECT_SINGLE);
-	owners->connect("item_rmb_selected", this, "_list_rmb_select");
-	owners->connect("item_activated", this, "_select_file");
+	owners->connect_compat("item_rmb_selected", this, "_list_rmb_select");
+	owners->connect_compat("item_activated", this, "_select_file");
 	owners->set_allow_rmb_select(true);
 	add_child(owners);
 }
@@ -800,7 +800,7 @@ OrphanResourcesDialog::OrphanResourcesDialog() {
 	add_child(delete_confirm);
 	dep_edit = memnew(DependencyEditor);
 	add_child(dep_edit);
-	delete_confirm->connect("confirmed", this, "_delete_confirm");
+	delete_confirm->connect_compat("confirmed", this, "_delete_confirm");
 	set_hide_on_ok(false);
 
 	VBoxContainer *vbc = memnew(VBoxContainer);
@@ -816,5 +816,5 @@ OrphanResourcesDialog::OrphanResourcesDialog() {
 	files->set_column_title(1, TTR("Owns"));
 	files->set_hide_root(true);
 	vbc->add_margin_child(TTR("Resources Without Explicit Ownership:"), files, true);
-	files->connect("button_pressed", this, "_button_pressed");
+	files->connect_compat("button_pressed", this, "_button_pressed");
 }

+ 7 - 6
editor/doc/doc_data.cpp

@@ -533,7 +533,7 @@ void DocData::generate(bool p_basic_types) {
 		ClassDoc &c = class_list[cname];
 		c.name = cname;
 
-		Variant::CallError cerror;
+		Callable::CallError cerror;
 		Variant v = Variant::construct(Variant::Type(i), NULL, 0, cerror);
 
 		List<MethodInfo> method_list;
@@ -562,11 +562,12 @@ void DocData::generate(bool p_basic_types) {
 				method.arguments.push_back(ad);
 			}
 
-			if (mi.return_val.type == Variant::NIL) {
-				if (mi.return_val.name != "")
-					method.return_type = "Variant";
-			} else {
-				method.return_type = Variant::get_type_name(mi.return_val.type);
+			return_doc_from_retinfo(method, mi.return_val);
+
+			if (mi.flags & METHOD_FLAG_VARARG) {
+				if (method.qualifiers != "")
+					method.qualifiers += " ";
+				method.qualifiers += "vararg";
 			}
 
 			c.methods.push_back(method);

+ 1 - 1
editor/editor_about.cpp

@@ -255,7 +255,7 @@ EditorAbout::EditorAbout() {
 	_tpl_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
 	tpl_hbc->add_child(_tpl_text);
 
-	_tpl_tree->connect("item_selected", this, "_license_tree_selected");
+	_tpl_tree->connect_compat("item_selected", this, "_license_tree_selected");
 	tpl_ti_all->select(0);
 	_tpl_text->set_text(tpl_ti_all->get_metadata(0));
 }

+ 1 - 1
editor/editor_asset_installer.cpp

@@ -318,7 +318,7 @@ EditorAssetInstaller::EditorAssetInstaller() {
 
 	tree = memnew(Tree);
 	vb->add_margin_child(TTR("Package Contents:"), tree, true);
-	tree->connect("item_edited", this, "_item_edited");
+	tree->connect_compat("item_edited", this, "_item_edited");
 
 	error = memnew(AcceptDialog);
 	add_child(error);

+ 28 - 28
editor/editor_audio_buses.cpp

@@ -799,8 +799,8 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
 	set_v_size_flags(SIZE_EXPAND_FILL);
 
 	track_name = memnew(LineEdit);
-	track_name->connect("text_entered", this, "_name_changed");
-	track_name->connect("focus_exited", this, "_name_focus_exit");
+	track_name->connect_compat("text_entered", this, "_name_changed");
+	track_name->connect_compat("focus_exited", this, "_name_focus_exit");
 	vb->add_child(track_name);
 
 	HBoxContainer *hbc = memnew(HBoxContainer);
@@ -809,19 +809,19 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
 	solo->set_toggle_mode(true);
 	solo->set_tooltip(TTR("Solo"));
 	solo->set_focus_mode(FOCUS_NONE);
-	solo->connect("pressed", this, "_solo_toggled");
+	solo->connect_compat("pressed", this, "_solo_toggled");
 	hbc->add_child(solo);
 	mute = memnew(ToolButton);
 	mute->set_toggle_mode(true);
 	mute->set_tooltip(TTR("Mute"));
 	mute->set_focus_mode(FOCUS_NONE);
-	mute->connect("pressed", this, "_mute_toggled");
+	mute->connect_compat("pressed", this, "_mute_toggled");
 	hbc->add_child(mute);
 	bypass = memnew(ToolButton);
 	bypass->set_toggle_mode(true);
 	bypass->set_tooltip(TTR("Bypass"));
 	bypass->set_focus_mode(FOCUS_NONE);
-	bypass->connect("pressed", this, "_bypass_toggled");
+	bypass->connect_compat("pressed", this, "_bypass_toggled");
 	hbc->add_child(bypass);
 	hbc->add_spacer();
 
@@ -878,9 +878,9 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
 	preview_timer->set_one_shot(true);
 	add_child(preview_timer);
 
-	slider->connect("value_changed", this, "_volume_changed");
-	slider->connect("value_changed", this, "_show_value");
-	preview_timer->connect("timeout", this, "_hide_value_preview");
+	slider->connect_compat("value_changed", this, "_volume_changed");
+	slider->connect_compat("value_changed", this, "_show_value");
+	preview_timer->connect_compat("timeout", this, "_hide_value_preview");
 	hb->add_child(slider);
 
 	cc = 0;
@@ -918,24 +918,24 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
 	effects->set_hide_folding(true);
 	effects->set_v_size_flags(SIZE_EXPAND_FILL);
 	vb->add_child(effects);
-	effects->connect("item_edited", this, "_effect_edited");
-	effects->connect("cell_selected", this, "_effect_selected");
+	effects->connect_compat("item_edited", this, "_effect_edited");
+	effects->connect_compat("cell_selected", this, "_effect_selected");
 	effects->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
 	effects->set_drag_forwarding(this);
-	effects->connect("item_rmb_selected", this, "_effect_rmb");
+	effects->connect_compat("item_rmb_selected", this, "_effect_rmb");
 	effects->set_allow_rmb_select(true);
 	effects->set_focus_mode(FOCUS_CLICK);
 	effects->set_allow_reselect(true);
 
 	send = memnew(OptionButton);
 	send->set_clip_text(true);
-	send->connect("item_selected", this, "_send_selected");
+	send->connect_compat("item_selected", this, "_send_selected");
 	vb->add_child(send);
 
 	set_focus_mode(FOCUS_CLICK);
 
 	effect_options = memnew(PopupMenu);
-	effect_options->connect("index_pressed", this, "_effect_add");
+	effect_options->connect_compat("index_pressed", this, "_effect_add");
 	add_child(effect_options);
 	List<StringName> effects;
 	ClassDB::get_inheriters_from_class("AudioEffect", &effects);
@@ -956,12 +956,12 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
 	bus_popup->add_item(TTR("Delete"));
 	bus_popup->set_item_disabled(1, is_master);
 	bus_popup->add_item(TTR("Reset Volume"));
-	bus_popup->connect("index_pressed", this, "_bus_popup_pressed");
+	bus_popup->connect_compat("index_pressed", this, "_bus_popup_pressed");
 
 	delete_effect_popup = memnew(PopupMenu);
 	delete_effect_popup->add_item(TTR("Delete Effect"));
 	add_child(delete_effect_popup);
-	delete_effect_popup->connect("index_pressed", this, "_delete_effect_pressed");
+	delete_effect_popup->connect_compat("index_pressed", this, "_delete_effect_pressed");
 }
 
 void EditorAudioBusDrop::_notification(int p_what) {
@@ -1029,11 +1029,11 @@ void EditorAudioBuses::_update_buses() {
 		bool is_master = (i == 0);
 		EditorAudioBus *audio_bus = memnew(EditorAudioBus(this, is_master));
 		bus_hb->add_child(audio_bus);
-		audio_bus->connect("delete_request", this, "_delete_bus", varray(audio_bus), CONNECT_DEFERRED);
-		audio_bus->connect("duplicate_request", this, "_duplicate_bus", varray(), CONNECT_DEFERRED);
-		audio_bus->connect("vol_reset_request", this, "_reset_bus_volume", varray(audio_bus), CONNECT_DEFERRED);
-		audio_bus->connect("drop_end_request", this, "_request_drop_end");
-		audio_bus->connect("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED);
+		audio_bus->connect_compat("delete_request", this, "_delete_bus", varray(audio_bus), CONNECT_DEFERRED);
+		audio_bus->connect_compat("duplicate_request", this, "_duplicate_bus", varray(), CONNECT_DEFERRED);
+		audio_bus->connect_compat("vol_reset_request", this, "_reset_bus_volume", varray(audio_bus), CONNECT_DEFERRED);
+		audio_bus->connect_compat("drop_end_request", this, "_request_drop_end");
+		audio_bus->connect_compat("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED);
 	}
 }
 
@@ -1187,7 +1187,7 @@ void EditorAudioBuses::_request_drop_end() {
 
 		bus_hb->add_child(drop_end);
 		drop_end->set_custom_minimum_size(Object::cast_to<Control>(bus_hb->get_child(0))->get_size());
-		drop_end->connect("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED);
+		drop_end->connect_compat("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED);
 	}
 }
 
@@ -1339,7 +1339,7 @@ EditorAudioBuses::EditorAudioBuses() {
 	top_hb->add_child(add);
 	add->set_text(TTR("Add Bus"));
 	add->set_tooltip(TTR("Add a new Audio Bus to this layout."));
-	add->connect("pressed", this, "_add_bus");
+	add->connect_compat("pressed", this, "_add_bus");
 
 	VSeparator *separator = memnew(VSeparator);
 	top_hb->add_child(separator);
@@ -1348,25 +1348,25 @@ EditorAudioBuses::EditorAudioBuses() {
 	load->set_text(TTR("Load"));
 	load->set_tooltip(TTR("Load an existing Bus Layout."));
 	top_hb->add_child(load);
-	load->connect("pressed", this, "_load_layout");
+	load->connect_compat("pressed", this, "_load_layout");
 
 	save_as = memnew(Button);
 	save_as->set_text(TTR("Save As"));
 	save_as->set_tooltip(TTR("Save this Bus Layout to a file."));
 	top_hb->add_child(save_as);
-	save_as->connect("pressed", this, "_save_as_layout");
+	save_as->connect_compat("pressed", this, "_save_as_layout");
 
 	_default = memnew(Button);
 	_default->set_text(TTR("Load Default"));
 	_default->set_tooltip(TTR("Load the default Bus Layout."));
 	top_hb->add_child(_default);
-	_default->connect("pressed", this, "_load_default_layout");
+	_default->connect_compat("pressed", this, "_load_default_layout");
 
 	_new = memnew(Button);
 	_new->set_text(TTR("Create"));
 	_new->set_tooltip(TTR("Create a new Bus Layout."));
 	top_hb->add_child(_new);
-	_new->connect("pressed", this, "_new_layout");
+	_new->connect_compat("pressed", this, "_new_layout");
 
 	bus_scroll = memnew(ScrollContainer);
 	bus_scroll->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1381,7 +1381,7 @@ EditorAudioBuses::EditorAudioBuses() {
 	save_timer->set_wait_time(0.8);
 	save_timer->set_one_shot(true);
 	add_child(save_timer);
-	save_timer->connect("timeout", this, "_server_save");
+	save_timer->connect_compat("timeout", this, "_server_save");
 
 	set_v_size_flags(SIZE_EXPAND_FILL);
 
@@ -1394,7 +1394,7 @@ EditorAudioBuses::EditorAudioBuses() {
 		file_dialog->add_filter("*." + E->get() + "; Audio Bus Layout");
 	}
 	add_child(file_dialog);
-	file_dialog->connect("file_selected", this, "_file_dialog_callback");
+	file_dialog->connect_compat("file_selected", this, "_file_dialog_callback");
 
 	set_process(true);
 }

+ 9 - 9
editor/editor_autoload_settings.cpp

@@ -835,8 +835,8 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 	autoload_add_path = memnew(EditorLineEditFileChooser);
 	autoload_add_path->set_h_size_flags(SIZE_EXPAND_FILL);
 	autoload_add_path->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-	autoload_add_path->get_file_dialog()->connect("file_selected", this, "_autoload_file_callback");
-	autoload_add_path->get_line_edit()->connect("text_changed", this, "_autoload_path_text_changed");
+	autoload_add_path->get_file_dialog()->connect_compat("file_selected", this, "_autoload_file_callback");
+	autoload_add_path->get_line_edit()->connect_compat("text_changed", this, "_autoload_path_text_changed");
 
 	hbc->add_child(autoload_add_path);
 
@@ -846,13 +846,13 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 
 	autoload_add_name = memnew(LineEdit);
 	autoload_add_name->set_h_size_flags(SIZE_EXPAND_FILL);
-	autoload_add_name->connect("text_entered", this, "_autoload_text_entered");
-	autoload_add_name->connect("text_changed", this, "_autoload_text_changed");
+	autoload_add_name->connect_compat("text_entered", this, "_autoload_text_entered");
+	autoload_add_name->connect_compat("text_changed", this, "_autoload_text_changed");
 	hbc->add_child(autoload_add_name);
 
 	add_autoload = memnew(Button);
 	add_autoload->set_text(TTR("Add"));
-	add_autoload->connect("pressed", this, "_autoload_add");
+	add_autoload->connect_compat("pressed", this, "_autoload_add");
 	// The button will be enabled once a valid name is entered (either automatically or manually).
 	add_autoload->set_disabled(true);
 	hbc->add_child(add_autoload);
@@ -882,10 +882,10 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 	tree->set_column_expand(3, false);
 	tree->set_column_min_width(3, 120 * EDSCALE);
 
-	tree->connect("cell_selected", this, "_autoload_selected");
-	tree->connect("item_edited", this, "_autoload_edited");
-	tree->connect("button_pressed", this, "_autoload_button_pressed");
-	tree->connect("item_activated", this, "_autoload_activated");
+	tree->connect_compat("cell_selected", this, "_autoload_selected");
+	tree->connect_compat("item_edited", this, "_autoload_edited");
+	tree->connect_compat("button_pressed", this, "_autoload_button_pressed");
+	tree->connect_compat("item_activated", this, "_autoload_activated");
 	tree->set_v_size_flags(SIZE_EXPAND_FILL);
 
 	add_child(tree, true);

+ 2 - 2
editor/editor_data.cpp

@@ -1024,7 +1024,7 @@ void EditorSelection::add_node(Node *p_node) {
 	}
 	selection[p_node] = meta;
 
-	p_node->connect("tree_exiting", this, "_node_removed", varray(p_node), CONNECT_ONESHOT);
+	p_node->connect_compat("tree_exiting", this, "_node_removed", varray(p_node), CONNECT_ONESHOT);
 
 	//emit_signal("selection_changed");
 }
@@ -1042,7 +1042,7 @@ void EditorSelection::remove_node(Node *p_node) {
 	if (meta)
 		memdelete(meta);
 	selection.erase(p_node);
-	p_node->disconnect("tree_exiting", this, "_node_removed");
+	p_node->disconnect_compat("tree_exiting", this, "_node_removed");
 	//emit_signal("selection_changed");
 }
 bool EditorSelection::is_selected(Node *p_node) const {

+ 10 - 10
editor/editor_dir_dialog.cpp

@@ -82,21 +82,21 @@ void EditorDirDialog::reload(const String &p_path) {
 void EditorDirDialog::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
-		EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload");
+		EditorFileSystem::get_singleton()->connect_compat("filesystem_changed", this, "reload");
 		reload();
 
-		if (!tree->is_connected("item_collapsed", this, "_item_collapsed")) {
-			tree->connect("item_collapsed", this, "_item_collapsed", varray(), CONNECT_DEFERRED);
+		if (!tree->is_connected_compat("item_collapsed", this, "_item_collapsed")) {
+			tree->connect_compat("item_collapsed", this, "_item_collapsed", varray(), CONNECT_DEFERRED);
 		}
 
-		if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed", this, "reload")) {
-			EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload");
+		if (!EditorFileSystem::get_singleton()->is_connected_compat("filesystem_changed", this, "reload")) {
+			EditorFileSystem::get_singleton()->connect_compat("filesystem_changed", this, "reload");
 		}
 	}
 
 	if (p_what == NOTIFICATION_EXIT_TREE) {
-		if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", this, "reload")) {
-			EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "reload");
+		if (EditorFileSystem::get_singleton()->is_connected_compat("filesystem_changed", this, "reload")) {
+			EditorFileSystem::get_singleton()->disconnect_compat("filesystem_changed", this, "reload");
 		}
 	}
 
@@ -186,10 +186,10 @@ EditorDirDialog::EditorDirDialog() {
 	tree = memnew(Tree);
 	add_child(tree);
 
-	tree->connect("item_activated", this, "_ok");
+	tree->connect_compat("item_activated", this, "_ok");
 
 	makedir = add_button(TTR("Create Folder"), OS::get_singleton()->get_swap_ok_cancel(), "makedir");
-	makedir->connect("pressed", this, "_make_dir");
+	makedir->connect_compat("pressed", this, "_make_dir");
 
 	makedialog = memnew(ConfirmationDialog);
 	makedialog->set_title(TTR("Create Folder"));
@@ -202,7 +202,7 @@ EditorDirDialog::EditorDirDialog() {
 	makedirname = memnew(LineEdit);
 	makevb->add_margin_child(TTR("Name:"), makedirname);
 	makedialog->register_text_enter(makedirname);
-	makedialog->connect("confirmed", this, "_make_dir_confirm");
+	makedialog->connect_compat("confirmed", this, "_make_dir_confirm");
 
 	mkdirerr = memnew(AcceptDialog);
 	mkdirerr->set_text(TTR("Could not create folder."));

+ 1 - 1
editor/editor_export.cpp

@@ -1416,7 +1416,7 @@ EditorExport::EditorExport() {
 	add_child(save_timer);
 	save_timer->set_wait_time(0.8);
 	save_timer->set_one_shot(true);
-	save_timer->connect("timeout", this, "_save");
+	save_timer->connect_compat("timeout", this, "_save");
 	block_save = false;
 
 	singleton = this;

+ 15 - 15
editor/editor_feature_profile.cpp

@@ -819,7 +819,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	profile_actions[PROFILE_CLEAR] = memnew(Button(TTR("Unset")));
 	name_hbc->add_child(profile_actions[PROFILE_CLEAR]);
 	profile_actions[PROFILE_CLEAR]->set_disabled(true);
-	profile_actions[PROFILE_CLEAR]->connect("pressed", this, "_profile_action", varray(PROFILE_CLEAR));
+	profile_actions[PROFILE_CLEAR]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_CLEAR));
 
 	main_vbc->add_margin_child(TTR("Current Profile:"), name_hbc);
 
@@ -827,34 +827,34 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	profile_list = memnew(OptionButton);
 	profile_list->set_h_size_flags(SIZE_EXPAND_FILL);
 	profiles_hbc->add_child(profile_list);
-	profile_list->connect("item_selected", this, "_profile_selected");
+	profile_list->connect_compat("item_selected", this, "_profile_selected");
 
 	profile_actions[PROFILE_SET] = memnew(Button(TTR("Make Current")));
 	profiles_hbc->add_child(profile_actions[PROFILE_SET]);
 	profile_actions[PROFILE_SET]->set_disabled(true);
-	profile_actions[PROFILE_SET]->connect("pressed", this, "_profile_action", varray(PROFILE_SET));
+	profile_actions[PROFILE_SET]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_SET));
 
 	profile_actions[PROFILE_ERASE] = memnew(Button(TTR("Remove")));
 	profiles_hbc->add_child(profile_actions[PROFILE_ERASE]);
 	profile_actions[PROFILE_ERASE]->set_disabled(true);
-	profile_actions[PROFILE_ERASE]->connect("pressed", this, "_profile_action", varray(PROFILE_ERASE));
+	profile_actions[PROFILE_ERASE]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_ERASE));
 
 	profiles_hbc->add_child(memnew(VSeparator));
 
 	profile_actions[PROFILE_NEW] = memnew(Button(TTR("New")));
 	profiles_hbc->add_child(profile_actions[PROFILE_NEW]);
-	profile_actions[PROFILE_NEW]->connect("pressed", this, "_profile_action", varray(PROFILE_NEW));
+	profile_actions[PROFILE_NEW]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_NEW));
 
 	profiles_hbc->add_child(memnew(VSeparator));
 
 	profile_actions[PROFILE_IMPORT] = memnew(Button(TTR("Import")));
 	profiles_hbc->add_child(profile_actions[PROFILE_IMPORT]);
-	profile_actions[PROFILE_IMPORT]->connect("pressed", this, "_profile_action", varray(PROFILE_IMPORT));
+	profile_actions[PROFILE_IMPORT]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_IMPORT));
 
 	profile_actions[PROFILE_EXPORT] = memnew(Button(TTR("Export")));
 	profiles_hbc->add_child(profile_actions[PROFILE_EXPORT]);
 	profile_actions[PROFILE_EXPORT]->set_disabled(true);
-	profile_actions[PROFILE_EXPORT]->connect("pressed", this, "_profile_action", varray(PROFILE_EXPORT));
+	profile_actions[PROFILE_EXPORT]->connect_compat("pressed", this, "_profile_action", varray(PROFILE_EXPORT));
 
 	main_vbc->add_margin_child(TTR("Available Profiles:"), profiles_hbc);
 
@@ -870,8 +870,8 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	class_list_vbc->add_margin_child(TTR("Enabled Classes:"), class_list, true);
 	class_list->set_hide_root(true);
 	class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
-	class_list->connect("cell_selected", this, "_class_list_item_selected");
-	class_list->connect("item_edited", this, "_class_list_item_edited", varray(), CONNECT_DEFERRED);
+	class_list->connect_compat("cell_selected", this, "_class_list_item_selected");
+	class_list->connect_compat("item_edited", this, "_class_list_item_edited", varray(), CONNECT_DEFERRED);
 
 	VBoxContainer *property_list_vbc = memnew(VBoxContainer);
 	h_split->add_child(property_list_vbc);
@@ -882,7 +882,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	property_list->set_hide_root(true);
 	property_list->set_hide_folding(true);
 	property_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true);
-	property_list->connect("item_edited", this, "_property_item_edited", varray(), CONNECT_DEFERRED);
+	property_list->connect_compat("item_edited", this, "_property_item_edited", varray(), CONNECT_DEFERRED);
 
 	new_profile_dialog = memnew(ConfirmationDialog);
 	new_profile_dialog->set_title(TTR("New profile name:"));
@@ -890,20 +890,20 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	new_profile_dialog->add_child(new_profile_name);
 	new_profile_name->set_custom_minimum_size(Size2(300 * EDSCALE, 1));
 	add_child(new_profile_dialog);
-	new_profile_dialog->connect("confirmed", this, "_create_new_profile");
+	new_profile_dialog->connect_compat("confirmed", this, "_create_new_profile");
 	new_profile_dialog->register_text_enter(new_profile_name);
 	new_profile_dialog->get_ok()->set_text(TTR("Create"));
 
 	erase_profile_dialog = memnew(ConfirmationDialog);
 	add_child(erase_profile_dialog);
 	erase_profile_dialog->set_title(TTR("Erase Profile"));
-	erase_profile_dialog->connect("confirmed", this, "_erase_selected_profile");
+	erase_profile_dialog->connect_compat("confirmed", this, "_erase_selected_profile");
 
 	import_profiles = memnew(EditorFileDialog);
 	add_child(import_profiles);
 	import_profiles->set_mode(EditorFileDialog::MODE_OPEN_FILES);
 	import_profiles->add_filter("*.profile; " + TTR("Godot Feature Profile"));
-	import_profiles->connect("files_selected", this, "_import_profiles");
+	import_profiles->connect_compat("files_selected", this, "_import_profiles");
 	import_profiles->set_title(TTR("Import Profile(s)"));
 	import_profiles->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
 
@@ -911,7 +911,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	add_child(export_profile);
 	export_profile->set_mode(EditorFileDialog::MODE_SAVE_FILE);
 	export_profile->add_filter("*.profile; " + TTR("Godot Feature Profile"));
-	export_profile->connect("file_selected", this, "_export_profile");
+	export_profile->connect_compat("file_selected", this, "_export_profile");
 	export_profile->set_title(TTR("Export Profile"));
 	export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
 
@@ -921,7 +921,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
 	update_timer = memnew(Timer);
 	update_timer->set_wait_time(1); //wait a second before updating editor
 	add_child(update_timer);
-	update_timer->connect("timeout", this, "_emit_current_profile_changed");
+	update_timer->connect_compat("timeout", this, "_emit_current_profile_changed");
 	update_timer->set_one_shot(true);
 
 	updating_features = false;

+ 31 - 31
editor/editor_file_dialog.cpp

@@ -1537,9 +1537,9 @@ EditorFileDialog::EditorFileDialog() {
 	pathhb->add_child(dir_next);
 	pathhb->add_child(dir_up);
 
-	dir_prev->connect("pressed", this, "_go_back");
-	dir_next->connect("pressed", this, "_go_forward");
-	dir_up->connect("pressed", this, "_go_up");
+	dir_prev->connect_compat("pressed", this, "_go_back");
+	dir_next->connect_compat("pressed", this, "_go_forward");
+	dir_up->connect_compat("pressed", this, "_go_up");
 
 	pathhb->add_child(memnew(Label(TTR("Path:"))));
 
@@ -1549,20 +1549,20 @@ EditorFileDialog::EditorFileDialog() {
 
 	refresh = memnew(ToolButton);
 	refresh->set_tooltip(TTR("Refresh files."));
-	refresh->connect("pressed", this, "_update_file_list");
+	refresh->connect_compat("pressed", this, "_update_file_list");
 	pathhb->add_child(refresh);
 
 	favorite = memnew(ToolButton);
 	favorite->set_toggle_mode(true);
 	favorite->set_tooltip(TTR("(Un)favorite current folder."));
-	favorite->connect("pressed", this, "_favorite_pressed");
+	favorite->connect_compat("pressed", this, "_favorite_pressed");
 	pathhb->add_child(favorite);
 
 	show_hidden = memnew(ToolButton);
 	show_hidden->set_toggle_mode(true);
 	show_hidden->set_pressed(is_showing_hidden_files());
 	show_hidden->set_tooltip(TTR("Toggle the visibility of hidden files."));
-	show_hidden->connect("toggled", this, "set_show_hidden_files");
+	show_hidden->connect_compat("toggled", this, "set_show_hidden_files");
 	pathhb->add_child(show_hidden);
 
 	pathhb->add_child(memnew(VSeparator));
@@ -1571,7 +1571,7 @@ EditorFileDialog::EditorFileDialog() {
 	view_mode_group.instance();
 
 	mode_thumbnails = memnew(ToolButton);
-	mode_thumbnails->connect("pressed", this, "set_display_mode", varray(DISPLAY_THUMBNAILS));
+	mode_thumbnails->connect_compat("pressed", this, "set_display_mode", varray(DISPLAY_THUMBNAILS));
 	mode_thumbnails->set_toggle_mode(true);
 	mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS);
 	mode_thumbnails->set_button_group(view_mode_group);
@@ -1579,7 +1579,7 @@ EditorFileDialog::EditorFileDialog() {
 	pathhb->add_child(mode_thumbnails);
 
 	mode_list = memnew(ToolButton);
-	mode_list->connect("pressed", this, "set_display_mode", varray(DISPLAY_LIST));
+	mode_list->connect_compat("pressed", this, "set_display_mode", varray(DISPLAY_LIST));
 	mode_list->set_toggle_mode(true);
 	mode_list->set_pressed(display_mode == DISPLAY_LIST);
 	mode_list->set_button_group(view_mode_group);
@@ -1588,11 +1588,11 @@ EditorFileDialog::EditorFileDialog() {
 
 	drives = memnew(OptionButton);
 	pathhb->add_child(drives);
-	drives->connect("item_selected", this, "_select_drive");
+	drives->connect_compat("item_selected", this, "_select_drive");
 
 	makedir = memnew(Button);
 	makedir->set_text(TTR("Create Folder"));
-	makedir->connect("pressed", this, "_make_dir");
+	makedir->connect_compat("pressed", this, "_make_dir");
 	pathhb->add_child(makedir);
 
 	list_hb = memnew(HSplitContainer);
@@ -1614,15 +1614,15 @@ EditorFileDialog::EditorFileDialog() {
 	fav_hb->add_spacer();
 	fav_up = memnew(ToolButton);
 	fav_hb->add_child(fav_up);
-	fav_up->connect("pressed", this, "_favorite_move_up");
+	fav_up->connect_compat("pressed", this, "_favorite_move_up");
 	fav_down = memnew(ToolButton);
 	fav_hb->add_child(fav_down);
-	fav_down->connect("pressed", this, "_favorite_move_down");
+	fav_down->connect_compat("pressed", this, "_favorite_move_down");
 
 	favorites = memnew(ItemList);
 	fav_vb->add_child(favorites);
 	favorites->set_v_size_flags(SIZE_EXPAND_FILL);
-	favorites->connect("item_selected", this, "_favorite_selected");
+	favorites->connect_compat("item_selected", this, "_favorite_selected");
 
 	VBoxContainer *rec_vb = memnew(VBoxContainer);
 	vsc->add_child(rec_vb);
@@ -1631,7 +1631,7 @@ EditorFileDialog::EditorFileDialog() {
 	recent = memnew(ItemList);
 	recent->set_allow_reselect(true);
 	rec_vb->add_margin_child(TTR("Recent:"), recent, true);
-	recent->connect("item_selected", this, "_recent_selected");
+	recent->connect_compat("item_selected", this, "_recent_selected");
 
 	VBoxContainer *item_vb = memnew(VBoxContainer);
 	list_hb->add_child(item_vb);
@@ -1650,13 +1650,13 @@ EditorFileDialog::EditorFileDialog() {
 
 	item_list = memnew(ItemList);
 	item_list->set_v_size_flags(SIZE_EXPAND_FILL);
-	item_list->connect("item_rmb_selected", this, "_item_list_item_rmb_selected");
-	item_list->connect("rmb_clicked", this, "_item_list_rmb_clicked");
+	item_list->connect_compat("item_rmb_selected", this, "_item_list_item_rmb_selected");
+	item_list->connect_compat("rmb_clicked", this, "_item_list_rmb_clicked");
 	item_list->set_allow_rmb_select(true);
 	list_vb->add_child(item_list);
 
 	item_menu = memnew(PopupMenu);
-	item_menu->connect("id_pressed", this, "_item_menu_id_pressed");
+	item_menu->connect_compat("id_pressed", this, "_item_menu_id_pressed");
 	add_child(item_menu);
 
 	// Other stuff.
@@ -1687,19 +1687,19 @@ EditorFileDialog::EditorFileDialog() {
 	access = ACCESS_RESOURCES;
 	_update_drives();
 
-	connect("confirmed", this, "_action_pressed");
-	item_list->connect("item_selected", this, "_item_selected", varray(), CONNECT_DEFERRED);
-	item_list->connect("multi_selected", this, "_multi_selected", varray(), CONNECT_DEFERRED);
-	item_list->connect("item_activated", this, "_item_db_selected", varray());
-	item_list->connect("nothing_selected", this, "_items_clear_selection");
-	dir->connect("text_entered", this, "_dir_entered");
-	file->connect("text_entered", this, "_file_entered");
-	filter->connect("item_selected", this, "_filter_selected");
+	connect_compat("confirmed", this, "_action_pressed");
+	item_list->connect_compat("item_selected", this, "_item_selected", varray(), CONNECT_DEFERRED);
+	item_list->connect_compat("multi_selected", this, "_multi_selected", varray(), CONNECT_DEFERRED);
+	item_list->connect_compat("item_activated", this, "_item_db_selected", varray());
+	item_list->connect_compat("nothing_selected", this, "_items_clear_selection");
+	dir->connect_compat("text_entered", this, "_dir_entered");
+	file->connect_compat("text_entered", this, "_file_entered");
+	filter->connect_compat("item_selected", this, "_filter_selected");
 
 	confirm_save = memnew(ConfirmationDialog);
 	confirm_save->set_as_toplevel(true);
 	add_child(confirm_save);
-	confirm_save->connect("confirmed", this, "_save_confirm_pressed");
+	confirm_save->connect_compat("confirmed", this, "_save_confirm_pressed");
 
 	remove_dialog = memnew(DependencyRemoveDialog);
 	add_child(remove_dialog);
@@ -1713,7 +1713,7 @@ EditorFileDialog::EditorFileDialog() {
 	makevb->add_margin_child(TTR("Name:"), makedirname);
 	add_child(makedialog);
 	makedialog->register_text_enter(makedirname);
-	makedialog->connect("confirmed", this, "_make_dir_confirm");
+	makedialog->connect_compat("confirmed", this, "_make_dir_confirm");
 	mkdirerr = memnew(AcceptDialog);
 	mkdirerr->set_text(TTR("Could not create folder."));
 	add_child(mkdirerr);
@@ -1777,10 +1777,10 @@ EditorLineEditFileChooser::EditorLineEditFileChooser() {
 	line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
 	button = memnew(Button);
 	add_child(button);
-	button->connect("pressed", this, "_browse");
+	button->connect_compat("pressed", this, "_browse");
 	dialog = memnew(EditorFileDialog);
 	add_child(dialog);
-	dialog->connect("file_selected", this, "_chosen");
-	dialog->connect("dir_selected", this, "_chosen");
-	dialog->connect("files_selected", this, "_chosen");
+	dialog->connect_compat("file_selected", this, "_chosen");
+	dialog->connect_compat("dir_selected", this, "_chosen");
+	dialog->connect_compat("files_selected", this, "_chosen");
 }

+ 9 - 9
editor/editor_help.cpp

@@ -1551,9 +1551,9 @@ EditorHelp::EditorHelp() {
 	class_desc->set_v_size_flags(SIZE_EXPAND_FILL);
 	class_desc->add_color_override("selection_color", get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
 
-	class_desc->connect("meta_clicked", this, "_class_desc_select");
-	class_desc->connect("gui_input", this, "_class_desc_input");
-	class_desc->connect("resized", this, "_class_desc_resized");
+	class_desc->connect_compat("meta_clicked", this, "_class_desc_select");
+	class_desc->connect_compat("gui_input", this, "_class_desc_input");
+	class_desc->connect_compat("resized", this, "_class_desc_resized");
 	_class_desc_resized();
 
 	// Added second so it opens at the bottom so it won't offset the entire widget.
@@ -1633,7 +1633,7 @@ EditorHelpBit::EditorHelpBit() {
 
 	rich_text = memnew(RichTextLabel);
 	add_child(rich_text);
-	rich_text->connect("meta_clicked", this, "_meta_clicked");
+	rich_text->connect_compat("meta_clicked", this, "_meta_clicked");
 	rich_text->add_color_override("selection_color", get_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
 	rich_text->set_override_selected_font_color(false);
 	set_custom_minimum_size(Size2(0, 70 * EDSCALE));
@@ -1645,8 +1645,8 @@ FindBar::FindBar() {
 	add_child(search_text);
 	search_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
 	search_text->set_h_size_flags(SIZE_EXPAND_FILL);
-	search_text->connect("text_changed", this, "_search_text_changed");
-	search_text->connect("text_entered", this, "_search_text_entered");
+	search_text->connect_compat("text_changed", this, "_search_text_changed");
+	search_text->connect_compat("text_entered", this, "_search_text_entered");
 
 	matches_label = memnew(Label);
 	add_child(matches_label);
@@ -1655,12 +1655,12 @@ FindBar::FindBar() {
 	find_prev = memnew(ToolButton);
 	add_child(find_prev);
 	find_prev->set_focus_mode(FOCUS_NONE);
-	find_prev->connect("pressed", this, "_search_prev");
+	find_prev->connect_compat("pressed", this, "_search_prev");
 
 	find_next = memnew(ToolButton);
 	add_child(find_next);
 	find_next->set_focus_mode(FOCUS_NONE);
-	find_next->connect("pressed", this, "_search_next");
+	find_next->connect_compat("pressed", this, "_search_next");
 
 	Control *space = memnew(Control);
 	add_child(space);
@@ -1671,7 +1671,7 @@ FindBar::FindBar() {
 	hide_button->set_focus_mode(FOCUS_NONE);
 	hide_button->set_expand(true);
 	hide_button->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED);
-	hide_button->connect("pressed", this, "_hide_pressed");
+	hide_button->connect_compat("pressed", this, "_hide_pressed");
 }
 
 void FindBar::popup_search() {

+ 8 - 8
editor/editor_help_search.cpp

@@ -111,7 +111,7 @@ void EditorHelpSearch::_notification(int p_what) {
 		} break;
 		case NOTIFICATION_ENTER_TREE: {
 
-			connect("confirmed", this, "_confirmed");
+			connect_compat("confirmed", this, "_confirmed");
 			_update_icons();
 		} break;
 		case NOTIFICATION_POPUP_HIDE: {
@@ -206,21 +206,21 @@ EditorHelpSearch::EditorHelpSearch() {
 	search_box = memnew(LineEdit);
 	search_box->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
 	search_box->set_h_size_flags(SIZE_EXPAND_FILL);
-	search_box->connect("gui_input", this, "_search_box_gui_input");
-	search_box->connect("text_changed", this, "_search_box_text_changed");
+	search_box->connect_compat("gui_input", this, "_search_box_gui_input");
+	search_box->connect_compat("text_changed", this, "_search_box_text_changed");
 	register_text_enter(search_box);
 	hbox->add_child(search_box);
 
 	case_sensitive_button = memnew(ToolButton);
 	case_sensitive_button->set_tooltip(TTR("Case Sensitive"));
-	case_sensitive_button->connect("pressed", this, "_update_results");
+	case_sensitive_button->connect_compat("pressed", this, "_update_results");
 	case_sensitive_button->set_toggle_mode(true);
 	case_sensitive_button->set_focus_mode(FOCUS_NONE);
 	hbox->add_child(case_sensitive_button);
 
 	hierarchy_button = memnew(ToolButton);
 	hierarchy_button->set_tooltip(TTR("Show Hierarchy"));
-	hierarchy_button->connect("pressed", this, "_update_results");
+	hierarchy_button->connect_compat("pressed", this, "_update_results");
 	hierarchy_button->set_toggle_mode(true);
 	hierarchy_button->set_pressed(true);
 	hierarchy_button->set_focus_mode(FOCUS_NONE);
@@ -237,7 +237,7 @@ EditorHelpSearch::EditorHelpSearch() {
 	filter_combo->add_item(TTR("Constants Only"), SEARCH_CONSTANTS);
 	filter_combo->add_item(TTR("Properties Only"), SEARCH_PROPERTIES);
 	filter_combo->add_item(TTR("Theme Properties Only"), SEARCH_THEME_ITEMS);
-	filter_combo->connect("item_selected", this, "_filter_combo_item_selected");
+	filter_combo->connect_compat("item_selected", this, "_filter_combo_item_selected");
 	hbox->add_child(filter_combo);
 
 	// Create the results tree.
@@ -251,8 +251,8 @@ EditorHelpSearch::EditorHelpSearch() {
 	results_tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE);
 	results_tree->set_hide_root(true);
 	results_tree->set_select_mode(Tree::SELECT_ROW);
-	results_tree->connect("item_activated", this, "_confirmed");
-	results_tree->connect("item_selected", get_ok(), "set_disabled", varray(false));
+	results_tree->connect_compat("item_activated", this, "_confirmed");
+	results_tree->connect_compat("item_selected", get_ok(), "set_disabled", varray(false));
 	vbox->add_child(results_tree, true);
 }
 

+ 25 - 25
editor/editor_inspector.cpp

@@ -570,7 +570,7 @@ void EditorProperty::_focusable_focused(int p_index) {
 
 void EditorProperty::add_focusable(Control *p_control) {
 
-	p_control->connect("focus_entered", this, "_focusable_focused", varray(focusables.size()));
+	p_control->connect_compat("focus_entered", this, "_focusable_focused", varray(focusables.size()));
 	focusables.push_back(p_control);
 }
 
@@ -925,7 +925,7 @@ bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_typ
 			&arg[0], &arg[1], &arg[2], &arg[3], &arg[4], &arg[5]
 		};
 
-		Variant::CallError err;
+		Callable::CallError err;
 		return get_script_instance()->call("parse_property", (const Variant **)&argptr, 6, err);
 	}
 	return false;
@@ -1339,14 +1339,14 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
 		if (ep) {
 
 			ep->object = object;
-			ep->connect("property_changed", this, "_property_changed");
-			ep->connect("property_keyed", this, "_property_keyed");
-			ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
-			ep->connect("property_checked", this, "_property_checked");
-			ep->connect("selected", this, "_property_selected");
-			ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
-			ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
-			ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
+			ep->connect_compat("property_changed", this, "_property_changed");
+			ep->connect_compat("property_keyed", this, "_property_keyed");
+			ep->connect_compat("property_keyed_with_value", this, "_property_keyed_with_value");
+			ep->connect_compat("property_checked", this, "_property_checked");
+			ep->connect_compat("selected", this, "_property_selected");
+			ep->connect_compat("multiple_properties_changed", this, "_multiple_properties_changed");
+			ep->connect_compat("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
+			ep->connect_compat("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
 
 			if (F->get().properties.size()) {
 
@@ -1751,17 +1751,17 @@ void EditorInspector::update_tree() {
 
 				if (ep) {
 
-					ep->connect("property_changed", this, "_property_changed");
+					ep->connect_compat("property_changed", this, "_property_changed");
 					if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
-						ep->connect("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
+						ep->connect_compat("property_changed", this, "_property_changed_update_all", varray(), CONNECT_DEFERRED);
 					}
-					ep->connect("property_keyed", this, "_property_keyed");
-					ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
-					ep->connect("property_checked", this, "_property_checked");
-					ep->connect("selected", this, "_property_selected");
-					ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
-					ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
-					ep->connect("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
+					ep->connect_compat("property_keyed", this, "_property_keyed");
+					ep->connect_compat("property_keyed_with_value", this, "_property_keyed_with_value");
+					ep->connect_compat("property_checked", this, "_property_checked");
+					ep->connect_compat("selected", this, "_property_selected");
+					ep->connect_compat("multiple_properties_changed", this, "_multiple_properties_changed");
+					ep->connect_compat("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
+					ep->connect_compat("object_id_selected", this, "_object_id_selected", varray(), CONNECT_DEFERRED);
 					if (doc_hint != String()) {
 						ep->set_tooltip(property_prefix + p.name + "::" + doc_hint);
 					} else {
@@ -1889,7 +1889,7 @@ void EditorInspector::set_use_filter(bool p_use) {
 void EditorInspector::register_text_enter(Node *p_line_edit) {
 	search_box = Object::cast_to<LineEdit>(p_line_edit);
 	if (search_box)
-		search_box->connect("text_changed", this, "_filter_changed");
+		search_box->connect_compat("text_changed", this, "_filter_changed");
 }
 
 void EditorInspector::_filter_changed(const String &p_text) {
@@ -2109,7 +2109,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
 			object->get_property_list(&pinfo);
 			for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
 				if (E->get().name == p_path) {
-					Variant::CallError ce;
+					Callable::CallError ce;
 					to_create = Variant::construct(E->get().type, NULL, 0, ce);
 					break;
 				}
@@ -2165,7 +2165,7 @@ void EditorInspector::_node_removed(Node *p_node) {
 void EditorInspector::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_READY) {
-		EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", this, "_feature_profile_changed");
+		EditorFeatureProfileManager::get_singleton()->connect_compat("current_feature_profile_changed", this, "_feature_profile_changed");
 	}
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -2174,7 +2174,7 @@ void EditorInspector::_notification(int p_what) {
 			add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
 		} else {
 			add_style_override("bg", get_stylebox("bg", "Tree"));
-			get_tree()->connect("node_removed", this, "_node_removed");
+			get_tree()->connect_compat("node_removed", this, "_node_removed");
 		}
 	}
 	if (p_what == NOTIFICATION_PREDELETE) {
@@ -2183,7 +2183,7 @@ void EditorInspector::_notification(int p_what) {
 	if (p_what == NOTIFICATION_EXIT_TREE) {
 
 		if (!sub_inspector) {
-			get_tree()->disconnect("node_removed", this, "_node_removed");
+			get_tree()->disconnect_compat("node_removed", this, "_node_removed");
 		}
 		edit(NULL);
 	}
@@ -2337,6 +2337,6 @@ EditorInspector::EditorInspector() {
 	property_focusable = -1;
 	sub_inspector = false;
 
-	get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed");
+	get_v_scrollbar()->connect_compat("value_changed", this, "_vscroll_changed");
 	update_scroll_request = -1;
 }

+ 2 - 2
editor/editor_layouts_dialog.cpp

@@ -128,8 +128,8 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
 	name->set_margin(MARGIN_TOP, 5);
 	name->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 5);
 	name->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -5);
-	name->connect("gui_input", this, "_line_gui_input");
-	name->connect("focus_entered", layout_names, "unselect_all");
+	name->connect_compat("gui_input", this, "_line_gui_input");
+	name->connect_compat("focus_entered", layout_names, "unselect_all");
 }
 
 void EditorLayoutsDialog::set_name_line_enabled(bool p_enabled) {

+ 2 - 2
editor/editor_log.cpp

@@ -159,13 +159,13 @@ EditorLog::EditorLog() {
 	hb->add_child(copybutton);
 	copybutton->set_text(TTR("Copy"));
 	copybutton->set_shortcut(ED_SHORTCUT("editor/copy_output", TTR("Copy Selection"), KEY_MASK_CMD | KEY_C));
-	copybutton->connect("pressed", this, "_copy_request");
+	copybutton->connect_compat("pressed", this, "_copy_request");
 
 	clearbutton = memnew(Button);
 	hb->add_child(clearbutton);
 	clearbutton->set_text(TTR("Clear"));
 	clearbutton->set_shortcut(ED_SHORTCUT("editor/clear_output", TTR("Clear Output"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K));
-	clearbutton->connect("pressed", this, "_clear_request");
+	clearbutton->connect_compat("pressed", this, "_clear_request");
 
 	log = memnew(RichTextLabel);
 	log->set_scroll_follow(true);

+ 3 - 3
editor/editor_network_profiler.cpp

@@ -142,12 +142,12 @@ EditorNetworkProfiler::EditorNetworkProfiler() {
 	activate = memnew(Button);
 	activate->set_toggle_mode(true);
 	activate->set_text(TTR("Start"));
-	activate->connect("pressed", this, "_activate_pressed");
+	activate->connect_compat("pressed", this, "_activate_pressed");
 	hb->add_child(activate);
 
 	clear_button = memnew(Button);
 	clear_button->set_text(TTR("Clear"));
-	clear_button->connect("pressed", this, "_clear_pressed");
+	clear_button->connect_compat("pressed", this, "_clear_pressed");
 	hb->add_child(clear_button);
 
 	hb->add_spacer();
@@ -207,5 +207,5 @@ EditorNetworkProfiler::EditorNetworkProfiler() {
 	frame_delay->set_wait_time(0.1);
 	frame_delay->set_one_shot(true);
 	add_child(frame_delay);
-	frame_delay->connect("timeout", this, "_update_frame");
+	frame_delay->connect_compat("timeout", this, "_update_frame");
 }

+ 82 - 82
editor/editor_node.cpp

@@ -374,8 +374,8 @@ void EditorNode::_notification(int p_what) {
 			get_tree()->get_root()->set_as_audio_listener(false);
 			get_tree()->get_root()->set_as_audio_listener_2d(false);
 			get_tree()->set_auto_accept_quit(false);
-			get_tree()->connect("files_dropped", this, "_dropped_files");
-			get_tree()->connect("global_menu_action", this, "_global_menu_action");
+			get_tree()->connect_compat("files_dropped", this, "_dropped_files");
+			get_tree()->connect_compat("global_menu_action", this, "_global_menu_action");
 
 			/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
 		} break;
@@ -2746,10 +2746,10 @@ void EditorNode::_tool_menu_option(int p_idx) {
 				Object *handler = ObjectDB::get_instance(params[0]);
 				String callback = params[1];
 				Variant *ud = &params[2];
-				Variant::CallError ce;
+				Callable::CallError ce;
 
 				handler->call(callback, (const Variant **)&ud, 1, ce);
-				if (ce.error != Variant::CallError::CALL_OK) {
+				if (ce.error != Callable::CallError::CALL_OK) {
 					String err = Variant::get_call_error_text(handler, callback, (const Variant **)&ud, 1, ce);
 					ERR_PRINT("Error calling function from tool menu: " + err);
 				}
@@ -2958,7 +2958,7 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed
 
 		ToolButton *tb = memnew(ToolButton);
 		tb->set_toggle_mode(true);
-		tb->connect("pressed", singleton, "_editor_select", varray(singleton->main_editor_buttons.size()));
+		tb->connect_compat("pressed", singleton, "_editor_select", varray(singleton->main_editor_buttons.size()));
 		tb->set_text(p_editor->get_name());
 		Ref<Texture2D> icon = p_editor->get_icon();
 
@@ -4785,7 +4785,7 @@ void EditorNode::_scene_tab_changed(int p_tab) {
 ToolButton *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
 
 	ToolButton *tb = memnew(ToolButton);
-	tb->connect("toggled", this, "_bottom_panel_switch", varray(bottom_panel_items.size()));
+	tb->connect_compat("toggled", this, "_bottom_panel_switch", varray(bottom_panel_items.size()));
 	tb->set_text(p_text);
 	tb->set_toggle_mode(true);
 	tb->set_focus_mode(Control::FOCUS_NONE);
@@ -4847,8 +4847,8 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
 	}
 
 	for (int i = 0; i < bottom_panel_items.size(); i++) {
-		bottom_panel_items[i].button->disconnect("toggled", this, "_bottom_panel_switch");
-		bottom_panel_items[i].button->connect("toggled", this, "_bottom_panel_switch", varray(i));
+		bottom_panel_items[i].button->disconnect_compat("toggled", this, "_bottom_panel_switch");
+		bottom_panel_items[i].button->connect_compat("toggled", this, "_bottom_panel_switch", varray(i));
 	}
 }
 
@@ -4869,8 +4869,8 @@ void EditorNode::remove_bottom_panel_item(Control *p_item) {
 	}
 
 	for (int i = 0; i < bottom_panel_items.size(); i++) {
-		bottom_panel_items[i].button->disconnect("toggled", this, "_bottom_panel_switch");
-		bottom_panel_items[i].button->connect("toggled", this, "_bottom_panel_switch", varray(i));
+		bottom_panel_items[i].button->disconnect_compat("toggled", this, "_bottom_panel_switch");
+		bottom_panel_items[i].button->connect_compat("toggled", this, "_bottom_panel_switch", varray(i));
 	}
 }
 
@@ -5925,8 +5925,8 @@ EditorNode::EditorNode() {
 	hsplits.push_back(right_hsplit);
 
 	for (int i = 0; i < vsplits.size(); i++) {
-		vsplits[i]->connect("dragged", this, "_dock_split_dragged");
-		hsplits[i]->connect("dragged", this, "_dock_split_dragged");
+		vsplits[i]->connect_compat("dragged", this, "_dock_split_dragged");
+		hsplits[i]->connect_compat("dragged", this, "_dock_split_dragged");
 	}
 
 	dock_select_popup = memnew(PopupPanel);
@@ -5938,7 +5938,7 @@ EditorNode::EditorNode() {
 	dock_tab_move_left = memnew(ToolButton);
 	dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons"));
 	dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE);
-	dock_tab_move_left->connect("pressed", this, "_dock_move_left");
+	dock_tab_move_left->connect_compat("pressed", this, "_dock_move_left");
 	dock_hb->add_child(dock_tab_move_left);
 
 	Label *dock_label = memnew(Label);
@@ -5950,16 +5950,16 @@ EditorNode::EditorNode() {
 	dock_tab_move_right = memnew(ToolButton);
 	dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons"));
 	dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE);
-	dock_tab_move_right->connect("pressed", this, "_dock_move_right");
+	dock_tab_move_right->connect_compat("pressed", this, "_dock_move_right");
 
 	dock_hb->add_child(dock_tab_move_right);
 	dock_vb->add_child(dock_hb);
 
 	dock_select = memnew(Control);
 	dock_select->set_custom_minimum_size(Size2(128, 64) * EDSCALE);
-	dock_select->connect("gui_input", this, "_dock_select_input");
-	dock_select->connect("draw", this, "_dock_select_draw");
-	dock_select->connect("mouse_exited", this, "_dock_popup_exit");
+	dock_select->connect_compat("gui_input", this, "_dock_select_input");
+	dock_select->connect_compat("draw", this, "_dock_select_draw");
+	dock_select->connect_compat("mouse_exited", this, "_dock_popup_exit");
 	dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL);
 	dock_vb->add_child(dock_select);
 
@@ -5970,11 +5970,11 @@ EditorNode::EditorNode() {
 		dock_slot[i]->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
 		dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
 		dock_slot[i]->set_popup(dock_select_popup);
-		dock_slot[i]->connect("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
+		dock_slot[i]->connect_compat("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
 		dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
 		dock_slot[i]->set_drag_to_rearrange_enabled(true);
 		dock_slot[i]->set_tabs_rearrange_group(1);
-		dock_slot[i]->connect("tab_changed", this, "_dock_tab_changed");
+		dock_slot[i]->connect_compat("tab_changed", this, "_dock_tab_changed");
 		dock_slot[i]->set_use_hidden_tabs_for_min_size(true);
 	}
 
@@ -5982,7 +5982,7 @@ EditorNode::EditorNode() {
 	add_child(dock_drag_timer);
 	dock_drag_timer->set_wait_time(0.5);
 	dock_drag_timer->set_one_shot(true);
-	dock_drag_timer->connect("timeout", this, "_save_docks");
+	dock_drag_timer->connect_compat("timeout", this, "_save_docks");
 
 	top_split = memnew(VSplitContainer);
 	center_split->add_child(top_split);
@@ -6015,21 +6015,21 @@ EditorNode::EditorNode() {
 	scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/scene_tabs/always_show_close_button", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
 	scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
 	scene_tabs->set_drag_to_rearrange_enabled(true);
-	scene_tabs->connect("tab_changed", this, "_scene_tab_changed");
-	scene_tabs->connect("right_button_pressed", this, "_scene_tab_script_edited");
-	scene_tabs->connect("tab_close", this, "_scene_tab_closed", varray(SCENE_TAB_CLOSE));
-	scene_tabs->connect("tab_hover", this, "_scene_tab_hover");
-	scene_tabs->connect("mouse_exited", this, "_scene_tab_exit");
-	scene_tabs->connect("gui_input", this, "_scene_tab_input");
-	scene_tabs->connect("reposition_active_tab_request", this, "_reposition_active_tab");
-	scene_tabs->connect("resized", this, "_update_scene_tabs");
+	scene_tabs->connect_compat("tab_changed", this, "_scene_tab_changed");
+	scene_tabs->connect_compat("right_button_pressed", this, "_scene_tab_script_edited");
+	scene_tabs->connect_compat("tab_close", this, "_scene_tab_closed", varray(SCENE_TAB_CLOSE));
+	scene_tabs->connect_compat("tab_hover", this, "_scene_tab_hover");
+	scene_tabs->connect_compat("mouse_exited", this, "_scene_tab_exit");
+	scene_tabs->connect_compat("gui_input", this, "_scene_tab_input");
+	scene_tabs->connect_compat("reposition_active_tab_request", this, "_reposition_active_tab");
+	scene_tabs->connect_compat("resized", this, "_update_scene_tabs");
 
 	tabbar_container = memnew(HBoxContainer);
 	scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
 
 	scene_tabs_context_menu = memnew(PopupMenu);
 	tabbar_container->add_child(scene_tabs_context_menu);
-	scene_tabs_context_menu->connect("id_pressed", this, "_menu_option");
+	scene_tabs_context_menu->connect_compat("id_pressed", this, "_menu_option");
 	scene_tabs_context_menu->set_hide_on_window_lose_focus(true);
 
 	srt->add_child(tabbar_container);
@@ -6041,7 +6041,7 @@ EditorNode::EditorNode() {
 	distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11));
 #endif
 	distraction_free->set_tooltip(TTR("Toggle distraction-free mode."));
-	distraction_free->connect("pressed", this, "_toggle_distraction_free_mode");
+	distraction_free->connect_compat("pressed", this, "_toggle_distraction_free_mode");
 	distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
 	distraction_free->set_toggle_mode(true);
 
@@ -6051,7 +6051,7 @@ EditorNode::EditorNode() {
 	scene_tab_add->set_tooltip(TTR("Add a new scene."));
 	scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons"));
 	scene_tab_add->add_color_override("icon_color_normal", Color(0.6f, 0.6f, 0.6f, 0.8f));
-	scene_tab_add->connect("pressed", this, "_menu_option", make_binds(FILE_NEW_SCENE));
+	scene_tab_add->connect_compat("pressed", this, "_menu_option", make_binds(FILE_NEW_SCENE));
 
 	scene_root_parent = memnew(PanelContainer);
 	scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
@@ -6086,14 +6086,14 @@ EditorNode::EditorNode() {
 	prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
 	prev_scene->set_tooltip(TTR("Go to previously opened scene."));
 	prev_scene->set_disabled(true);
-	prev_scene->connect("pressed", this, "_menu_option", make_binds(FILE_OPEN_PREV));
+	prev_scene->connect_compat("pressed", this, "_menu_option", make_binds(FILE_OPEN_PREV));
 	gui_base->add_child(prev_scene);
 	prev_scene->set_position(Point2(3, 24));
 	prev_scene->hide();
 
 	accept = memnew(AcceptDialog);
 	gui_base->add_child(accept);
-	accept->connect("confirmed", this, "_menu_confirm_current");
+	accept->connect_compat("confirmed", this, "_menu_confirm_current");
 
 	project_export = memnew(ProjectExportDialog);
 	gui_base->add_child(project_export);
@@ -6120,12 +6120,12 @@ EditorNode::EditorNode() {
 	gui_base->add_child(feature_profile_manager);
 	about = memnew(EditorAbout);
 	gui_base->add_child(about);
-	feature_profile_manager->connect("current_feature_profile_changed", this, "_feature_profile_changed");
+	feature_profile_manager->connect_compat("current_feature_profile_changed", this, "_feature_profile_changed");
 
 	warning = memnew(AcceptDialog);
 	warning->add_button(TTR("Copy Text"), true, "copy");
 	gui_base->add_child(warning);
-	warning->connect("custom_action", this, "_copy_warning");
+	warning->connect_compat("custom_action", this, "_copy_warning");
 
 	ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB);
 	ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB);
@@ -6159,7 +6159,7 @@ EditorNode::EditorNode() {
 	p->add_submenu_item(TTR("Convert To..."), "Export");
 	pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_MeshLibrary", TTR("MeshLibrary...")), FILE_EXPORT_MESH_LIBRARY);
 	pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_TileSet", TTR("TileSet...")), FILE_EXPORT_TILESET);
-	pm_export->connect("id_pressed", this, "_menu_option");
+	pm_export->connect_compat("id_pressed", this, "_menu_option");
 
 	p->add_separator();
 	p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
@@ -6172,7 +6172,7 @@ EditorNode::EditorNode() {
 	recent_scenes = memnew(PopupMenu);
 	recent_scenes->set_name("RecentScenes");
 	p->add_child(recent_scenes);
-	recent_scenes->connect("id_pressed", this, "_open_recent_scene");
+	recent_scenes->connect_compat("id_pressed", this, "_open_recent_scene");
 
 	p->add_separator();
 	p->add_shortcut(ED_SHORTCUT("editor/file_quit", TTR("Quit"), KEY_MASK_CMD + KEY_Q), FILE_QUIT, true);
@@ -6188,11 +6188,11 @@ EditorNode::EditorNode() {
 	p = project_menu->get_popup();
 	p->set_hide_on_window_lose_focus(true);
 	p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings...")), RUN_SETTINGS);
-	p->connect("id_pressed", this, "_menu_option");
+	p->connect_compat("id_pressed", this, "_menu_option");
 
 	vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
 	vcs_actions_menu->set_name("Version Control");
-	vcs_actions_menu->connect("index_pressed", this, "_version_control_menu_option");
+	vcs_actions_menu->connect_compat("index_pressed", this, "_version_control_menu_option");
 	p->add_separator();
 	p->add_child(vcs_actions_menu);
 	p->add_submenu_item(TTR("Version Control"), "Version Control");
@@ -6205,12 +6205,12 @@ EditorNode::EditorNode() {
 	p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
 
 	plugin_config_dialog = memnew(PluginConfigDialog);
-	plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
+	plugin_config_dialog->connect_compat("plugin_ready", this, "_on_plugin_ready");
 	gui_base->add_child(plugin_config_dialog);
 
 	tool_menu = memnew(PopupMenu);
 	tool_menu->set_name("Tools");
-	tool_menu->connect("index_pressed", this, "_tool_menu_option");
+	tool_menu->connect_compat("index_pressed", this, "_tool_menu_option");
 	p->add_child(tool_menu);
 	p->add_submenu_item(TTR("Tools"), "Tools");
 	tool_menu->add_item(TTR("Orphan Resource Explorer..."), TOOLS_ORPHAN_RESOURCES);
@@ -6254,7 +6254,7 @@ EditorNode::EditorNode() {
 	p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Sync Script Changes")), RUN_RELOAD_SCRIPTS);
 	p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
 	p->set_item_checked(p->get_item_count() - 1, true);
-	p->connect("id_pressed", this, "_menu_option");
+	p->connect_compat("id_pressed", this, "_menu_option");
 
 	menu_hb->add_spacer();
 
@@ -6273,7 +6273,7 @@ EditorNode::EditorNode() {
 	editor_layouts = memnew(PopupMenu);
 	editor_layouts->set_name("Layouts");
 	p->add_child(editor_layouts);
-	editor_layouts->connect("id_pressed", this, "_layout_menu_option");
+	editor_layouts->connect_compat("id_pressed", this, "_layout_menu_option");
 	p->add_submenu_item(TTR("Editor Layout"), "Layouts");
 	p->add_separator();
 #ifdef OSX_ENABLED
@@ -6315,7 +6315,7 @@ EditorNode::EditorNode() {
 
 	p = help_menu->get_popup();
 	p->set_hide_on_window_lose_focus(true);
-	p->connect("id_pressed", this, "_menu_option");
+	p->connect_compat("id_pressed", this, "_menu_option");
 	p->add_icon_shortcut(gui_base->get_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_MASK_SHIFT | KEY_F1), HELP_SEARCH);
 	p->add_separator();
 	p->add_icon_shortcut(gui_base->get_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS);
@@ -6333,7 +6333,7 @@ EditorNode::EditorNode() {
 	play_button->set_toggle_mode(true);
 	play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons"));
 	play_button->set_focus_mode(Control::FOCUS_NONE);
-	play_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY));
+	play_button->connect_compat("pressed", this, "_menu_option", make_binds(RUN_PLAY));
 	play_button->set_tooltip(TTR("Play the project."));
 #ifdef OSX_ENABLED
 	play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_MASK_CMD | KEY_B));
@@ -6358,7 +6358,7 @@ EditorNode::EditorNode() {
 	play_hb->add_child(stop_button);
 	stop_button->set_focus_mode(Control::FOCUS_NONE);
 	stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons"));
-	stop_button->connect("pressed", this, "_menu_option", make_binds(RUN_STOP));
+	stop_button->connect_compat("pressed", this, "_menu_option", make_binds(RUN_STOP));
 	stop_button->set_tooltip(TTR("Stop the scene."));
 	stop_button->set_disabled(true);
 #ifdef OSX_ENABLED
@@ -6369,14 +6369,14 @@ EditorNode::EditorNode() {
 
 	run_native = memnew(EditorRunNative);
 	play_hb->add_child(run_native);
-	run_native->connect("native_run", this, "_menu_option", varray(RUN_PLAY_NATIVE));
+	run_native->connect_compat("native_run", this, "_menu_option", varray(RUN_PLAY_NATIVE));
 
 	play_scene_button = memnew(ToolButton);
 	play_hb->add_child(play_scene_button);
 	play_scene_button->set_toggle_mode(true);
 	play_scene_button->set_focus_mode(Control::FOCUS_NONE);
 	play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
-	play_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_SCENE));
+	play_scene_button->connect_compat("pressed", this, "_menu_option", make_binds(RUN_PLAY_SCENE));
 	play_scene_button->set_tooltip(TTR("Play the edited scene."));
 #ifdef OSX_ENABLED
 	play_scene_button->set_shortcut(ED_SHORTCUT("editor/play_scene", TTR("Play Scene"), KEY_MASK_CMD | KEY_R));
@@ -6389,7 +6389,7 @@ EditorNode::EditorNode() {
 	play_custom_scene_button->set_toggle_mode(true);
 	play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE);
 	play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
-	play_custom_scene_button->connect("pressed", this, "_menu_option", make_binds(RUN_PLAY_CUSTOM_SCENE));
+	play_custom_scene_button->connect_compat("pressed", this, "_menu_option", make_binds(RUN_PLAY_CUSTOM_SCENE));
 	play_custom_scene_button->set_tooltip(TTR("Play custom scene"));
 #ifdef OSX_ENABLED
 	play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R));
@@ -6404,7 +6404,7 @@ EditorNode::EditorNode() {
 	video_driver = memnew(OptionButton);
 	video_driver->set_flat(true);
 	video_driver->set_focus_mode(Control::FOCUS_NONE);
-	video_driver->connect("item_selected", this, "_video_driver_selected");
+	video_driver->connect_compat("item_selected", this, "_video_driver_selected");
 	video_driver->add_font_override("font", gui_base->get_font("bold", "EditorFonts"));
 	// TODO re-enable when GLES2 is ported
 	video_driver->set_disabled(true);
@@ -6429,7 +6429,7 @@ EditorNode::EditorNode() {
 	video_restart_dialog = memnew(ConfirmationDialog);
 	video_restart_dialog->set_text(TTR("Changing the video driver requires restarting the editor."));
 	video_restart_dialog->get_ok()->set_text(TTR("Save & Restart"));
-	video_restart_dialog->connect("confirmed", this, "_menu_option", varray(SET_VIDEO_DRIVER_SAVE_AND_RESTART));
+	video_restart_dialog->connect_compat("confirmed", this, "_menu_option", varray(SET_VIDEO_DRIVER_SAVE_AND_RESTART));
 	gui_base->add_child(video_restart_dialog);
 
 	progress_hb = memnew(BackgroundProgress);
@@ -6438,13 +6438,13 @@ EditorNode::EditorNode() {
 	gui_base->add_child(layout_dialog);
 	layout_dialog->set_hide_on_ok(false);
 	layout_dialog->set_size(Size2(225, 270) * EDSCALE);
-	layout_dialog->connect("name_confirmed", this, "_dialog_action");
+	layout_dialog->connect_compat("name_confirmed", this, "_dialog_action");
 
 	update_spinner = memnew(MenuButton);
 	update_spinner->set_tooltip(TTR("Spins when the editor window redraws."));
 	right_menu_hb->add_child(update_spinner);
 	update_spinner->set_icon(gui_base->get_icon("Progress1", "EditorIcons"));
-	update_spinner->get_popup()->connect("id_pressed", this, "_menu_option");
+	update_spinner->get_popup()->connect_compat("id_pressed", this, "_menu_option");
 	p = update_spinner->get_popup();
 	p->add_radio_check_item(TTR("Update Continuously"), SETTINGS_UPDATE_CONTINUOUSLY);
 	p->add_radio_check_item(TTR("Update When Changed"), SETTINGS_UPDATE_WHEN_CHANGED);
@@ -6460,9 +6460,9 @@ EditorNode::EditorNode() {
 	node_dock = memnew(NodeDock);
 
 	filesystem_dock = memnew(FileSystemDock(this));
-	filesystem_dock->connect("inherit", this, "_inherit_request");
-	filesystem_dock->connect("instance", this, "_instance_request");
-	filesystem_dock->connect("display_mode_changed", this, "_save_docks");
+	filesystem_dock->connect_compat("inherit", this, "_inherit_request");
+	filesystem_dock->connect_compat("instance", this, "_instance_request");
+	filesystem_dock->connect_compat("display_mode_changed", this, "_save_docks");
 
 	// Scene: Top left
 	dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock);
@@ -6548,7 +6548,7 @@ EditorNode::EditorNode() {
 	bottom_panel_hb->add_child(bottom_panel_raise);
 	bottom_panel_raise->hide();
 	bottom_panel_raise->set_toggle_mode(true);
-	bottom_panel_raise->connect("toggled", this, "_bottom_panel_raise_toggled");
+	bottom_panel_raise->connect_compat("toggled", this, "_bottom_panel_raise_toggled");
 
 	log = memnew(EditorLog);
 	ToolButton *output_button = add_bottom_panel_item(TTR("Output"), log);
@@ -6556,37 +6556,37 @@ EditorNode::EditorNode() {
 
 	old_split_ofs = 0;
 
-	center_split->connect("resized", this, "_vp_resized");
+	center_split->connect_compat("resized", this, "_vp_resized");
 
 	orphan_resources = memnew(OrphanResourcesDialog);
 	gui_base->add_child(orphan_resources);
 
 	confirmation = memnew(ConfirmationDialog);
 	gui_base->add_child(confirmation);
-	confirmation->connect("confirmed", this, "_menu_confirm_current");
+	confirmation->connect_compat("confirmed", this, "_menu_confirm_current");
 
 	save_confirmation = memnew(ConfirmationDialog);
 	save_confirmation->add_button(TTR("Don't Save"), OS::get_singleton()->get_swap_ok_cancel(), "discard");
 	gui_base->add_child(save_confirmation);
-	save_confirmation->connect("confirmed", this, "_menu_confirm_current");
-	save_confirmation->connect("custom_action", this, "_discard_changes");
+	save_confirmation->connect_compat("confirmed", this, "_menu_confirm_current");
+	save_confirmation->connect_compat("custom_action", this, "_discard_changes");
 
 	custom_build_manage_templates = memnew(ConfirmationDialog);
 	custom_build_manage_templates->set_text(TTR("Android build template is missing, please install relevant templates."));
 	custom_build_manage_templates->get_ok()->set_text(TTR("Manage Templates"));
-	custom_build_manage_templates->connect("confirmed", this, "_menu_option", varray(SETTINGS_MANAGE_EXPORT_TEMPLATES));
+	custom_build_manage_templates->connect_compat("confirmed", this, "_menu_option", varray(SETTINGS_MANAGE_EXPORT_TEMPLATES));
 	gui_base->add_child(custom_build_manage_templates);
 
 	install_android_build_template = memnew(ConfirmationDialog);
 	install_android_build_template->set_text(TTR("This will set up your project for custom Android builds by installing the source template to \"res://android/build\".\nYou can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.).\nNote that in order to make custom builds instead of using pre-built APKs, the \"Use Custom Build\" option should be enabled in the Android export preset."));
 	install_android_build_template->get_ok()->set_text(TTR("Install"));
-	install_android_build_template->connect("confirmed", this, "_menu_confirm_current");
+	install_android_build_template->connect_compat("confirmed", this, "_menu_confirm_current");
 	gui_base->add_child(install_android_build_template);
 
 	remove_android_build_template = memnew(ConfirmationDialog);
 	remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again."));
 	remove_android_build_template->get_ok()->set_text(TTR("Show in File Manager"));
-	remove_android_build_template->connect("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
+	remove_android_build_template->connect_compat("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
 	gui_base->add_child(remove_android_build_template);
 
 	file_templates = memnew(EditorFileDialog);
@@ -6605,7 +6605,7 @@ EditorNode::EditorNode() {
 	file_export_lib = memnew(EditorFileDialog);
 	file_export_lib->set_title(TTR("Export Library"));
 	file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE);
-	file_export_lib->connect("file_selected", this, "_dialog_action");
+	file_export_lib->connect_compat("file_selected", this, "_dialog_action");
 	file_export_lib_merge = memnew(CheckBox);
 	file_export_lib_merge->set_text(TTR("Merge With Existing"));
 	file_export_lib_merge->set_pressed(true);
@@ -6622,16 +6622,16 @@ EditorNode::EditorNode() {
 		file_script->add_filter("*." + E->get());
 	}
 	gui_base->add_child(file_script);
-	file_script->connect("file_selected", this, "_dialog_action");
+	file_script->connect_compat("file_selected", this, "_dialog_action");
 
-	file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
-	file_menu->connect("about_to_show", this, "_update_file_menu_opened");
-	file_menu->get_popup()->connect("popup_hide", this, "_update_file_menu_closed");
+	file_menu->get_popup()->connect_compat("id_pressed", this, "_menu_option");
+	file_menu->connect_compat("about_to_show", this, "_update_file_menu_opened");
+	file_menu->get_popup()->connect_compat("popup_hide", this, "_update_file_menu_closed");
 
-	settings_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+	settings_menu->get_popup()->connect_compat("id_pressed", this, "_menu_option");
 
-	file->connect("file_selected", this, "_dialog_action");
-	file_templates->connect("file_selected", this, "_dialog_action");
+	file->connect_compat("file_selected", this, "_dialog_action");
+	file_templates->connect_compat("file_selected", this, "_dialog_action");
 
 	preview_gen = memnew(AudioStreamPreviewGenerator);
 	add_child(preview_gen);
@@ -6767,8 +6767,8 @@ EditorNode::EditorNode() {
 	open_imported = memnew(ConfirmationDialog);
 	open_imported->get_ok()->set_text(TTR("Open Anyway"));
 	new_inherited_button = open_imported->add_button(TTR("New Inherited"), !OS::get_singleton()->get_swap_ok_cancel(), "inherit");
-	open_imported->connect("confirmed", this, "_open_imported");
-	open_imported->connect("custom_action", this, "_inherit_imported");
+	open_imported->connect_compat("confirmed", this, "_open_imported");
+	open_imported->connect_compat("custom_action", this, "_inherit_imported");
 	gui_base->add_child(open_imported);
 
 	saved_version = 1;
@@ -6777,11 +6777,11 @@ EditorNode::EditorNode() {
 
 	quick_open = memnew(EditorQuickOpen);
 	gui_base->add_child(quick_open);
-	quick_open->connect("quick_open", this, "_quick_opened");
+	quick_open->connect_compat("quick_open", this, "_quick_opened");
 
 	quick_run = memnew(EditorQuickOpen);
 	gui_base->add_child(quick_run);
-	quick_run->connect("quick_open", this, "_quick_run");
+	quick_run->connect_compat("quick_open", this, "_quick_run");
 
 	_update_recent_scenes();
 
@@ -6803,10 +6803,10 @@ EditorNode::EditorNode() {
 	execute_output_dialog->set_title("");
 	gui_base->add_child(execute_output_dialog);
 
-	EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed");
-	EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed");
-	EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported");
-	EditorFileSystem::get_singleton()->connect("resources_reload", this, "_resources_changed");
+	EditorFileSystem::get_singleton()->connect_compat("sources_changed", this, "_sources_changed");
+	EditorFileSystem::get_singleton()->connect_compat("filesystem_changed", this, "_fs_changed");
+	EditorFileSystem::get_singleton()->connect_compat("resources_reimported", this, "_resources_reimported");
+	EditorFileSystem::get_singleton()->connect_compat("resources_reload", this, "_resources_changed");
 
 	_build_icon_type_cache();
 
@@ -6815,7 +6815,7 @@ EditorNode::EditorNode() {
 	pick_main_scene = memnew(ConfirmationDialog);
 	gui_base->add_child(pick_main_scene);
 	pick_main_scene->get_ok()->set_text(TTR("Select"));
-	pick_main_scene->connect("confirmed", this, "_menu_option", varray(SETTINGS_PICK_MAIN_SCENE));
+	pick_main_scene->connect_compat("confirmed", this, "_menu_option", varray(SETTINGS_PICK_MAIN_SCENE));
 
 	for (int i = 0; i < _init_callbacks.size(); i++)
 		_init_callbacks[i]();
@@ -6855,7 +6855,7 @@ EditorNode::EditorNode() {
 	screenshot_timer = memnew(Timer);
 	screenshot_timer->set_one_shot(true);
 	screenshot_timer->set_wait_time(settings_menu->get_popup()->get_submenu_popup_delay() + 0.1f);
-	screenshot_timer->connect("timeout", this, "_request_screenshot");
+	screenshot_timer->connect_compat("timeout", this, "_request_screenshot");
 	add_child(screenshot_timer);
 	screenshot_timer->set_owner(get_owner());
 }

+ 2 - 2
editor/editor_path.cpp

@@ -152,6 +152,6 @@ EditorPath::EditorPath(EditorHistory *p_history) {
 	history = p_history;
 	set_clip_text(true);
 	set_text_align(ALIGN_LEFT);
-	get_popup()->connect("about_to_show", this, "_about_to_show");
-	get_popup()->connect("id_pressed", this, "_id_pressed");
+	get_popup()->connect_compat("about_to_show", this, "_about_to_show");
+	get_popup()->connect_compat("id_pressed", this, "_id_pressed");
 }

+ 5 - 5
editor/editor_plugin_settings.cpp

@@ -43,8 +43,8 @@ void EditorPluginSettings::_notification(int p_what) {
 	if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
 		update_plugins();
 	} else if (p_what == Node::NOTIFICATION_READY) {
-		plugin_config_dialog->connect("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
-		plugin_list->connect("button_pressed", this, "_cell_button_pressed");
+		plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
+		plugin_list->connect_compat("button_pressed", this, "_cell_button_pressed");
 	}
 }
 
@@ -219,10 +219,10 @@ EditorPluginSettings::EditorPluginSettings() {
 	title_hb->add_child(memnew(Label(TTR("Installed Plugins:"))));
 	title_hb->add_spacer();
 	create_plugin = memnew(Button(TTR("Create")));
-	create_plugin->connect("pressed", this, "_create_clicked");
+	create_plugin->connect_compat("pressed", this, "_create_clicked");
 	title_hb->add_child(create_plugin);
 	update_list = memnew(Button(TTR("Update")));
-	update_list->connect("pressed", this, "update_plugins");
+	update_list->connect_compat("pressed", this, "update_plugins");
 	title_hb->add_child(update_list);
 	add_child(title_hb);
 
@@ -245,7 +245,7 @@ EditorPluginSettings::EditorPluginSettings() {
 	plugin_list->set_column_min_width(3, 80 * EDSCALE);
 	plugin_list->set_column_min_width(4, 40 * EDSCALE);
 	plugin_list->set_hide_root(true);
-	plugin_list->connect("item_edited", this, "_plugin_activity_changed");
+	plugin_list->connect_compat("item_edited", this, "_plugin_activity_changed");
 
 	VBoxContainer *mc = memnew(VBoxContainer);
 	mc->add_child(plugin_list);

+ 11 - 11
editor/editor_profiler.cpp

@@ -686,12 +686,12 @@ EditorProfiler::EditorProfiler() {
 	activate = memnew(Button);
 	activate->set_toggle_mode(true);
 	activate->set_text(TTR("Start"));
-	activate->connect("pressed", this, "_activate_pressed");
+	activate->connect_compat("pressed", this, "_activate_pressed");
 	hb->add_child(activate);
 
 	clear_button = memnew(Button);
 	clear_button->set_text(TTR("Clear"));
-	clear_button->connect("pressed", this, "_clear_pressed");
+	clear_button->connect_compat("pressed", this, "_clear_pressed");
 	hb->add_child(clear_button);
 
 	hb->add_child(memnew(Label(TTR("Measure:"))));
@@ -701,7 +701,7 @@ EditorProfiler::EditorProfiler() {
 	display_mode->add_item(TTR("Average Time (sec)"));
 	display_mode->add_item(TTR("Frame %"));
 	display_mode->add_item(TTR("Physics Frame %"));
-	display_mode->connect("item_selected", this, "_combo_changed");
+	display_mode->connect_compat("item_selected", this, "_combo_changed");
 
 	hb->add_child(display_mode);
 
@@ -710,7 +710,7 @@ EditorProfiler::EditorProfiler() {
 	display_time = memnew(OptionButton);
 	display_time->add_item(TTR("Inclusive"));
 	display_time->add_item(TTR("Self"));
-	display_time->connect("item_selected", this, "_combo_changed");
+	display_time->connect_compat("item_selected", this, "_combo_changed");
 
 	hb->add_child(display_time);
 
@@ -721,7 +721,7 @@ EditorProfiler::EditorProfiler() {
 	cursor_metric_edit = memnew(SpinBox);
 	cursor_metric_edit->set_h_size_flags(SIZE_FILL);
 	hb->add_child(cursor_metric_edit);
-	cursor_metric_edit->connect("value_changed", this, "_cursor_metric_changed");
+	cursor_metric_edit->connect_compat("value_changed", this, "_cursor_metric_changed");
 
 	hb->add_constant_override("separation", 8 * EDSCALE);
 
@@ -745,14 +745,14 @@ EditorProfiler::EditorProfiler() {
 	variables->set_column_title(2, TTR("Calls"));
 	variables->set_column_expand(2, false);
 	variables->set_column_min_width(2, 60 * EDSCALE);
-	variables->connect("item_edited", this, "_item_edited");
+	variables->connect_compat("item_edited", this, "_item_edited");
 
 	graph = memnew(TextureRect);
 	graph->set_expand(true);
 	graph->set_mouse_filter(MOUSE_FILTER_STOP);
-	graph->connect("draw", this, "_graph_tex_draw");
-	graph->connect("gui_input", this, "_graph_tex_input");
-	graph->connect("mouse_exited", this, "_graph_tex_mouse_exit");
+	graph->connect_compat("draw", this, "_graph_tex_draw");
+	graph->connect_compat("gui_input", this, "_graph_tex_input");
+	graph->connect_compat("mouse_exited", this, "_graph_tex_mouse_exit");
 
 	h_split->add_child(graph);
 	graph->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -768,13 +768,13 @@ EditorProfiler::EditorProfiler() {
 	frame_delay->set_wait_time(0.1);
 	frame_delay->set_one_shot(true);
 	add_child(frame_delay);
-	frame_delay->connect("timeout", this, "_update_frame");
+	frame_delay->connect_compat("timeout", this, "_update_frame");
 
 	plot_delay = memnew(Timer);
 	plot_delay->set_wait_time(0.1);
 	plot_delay->set_one_shot(true);
 	add_child(plot_delay);
-	plot_delay->connect("timeout", this, "_update_plot");
+	plot_delay->connect_compat("timeout", this, "_update_plot");
 
 	plot_sigs.insert("physics_frame_time");
 	plot_sigs.insert("category_frame_time");

+ 57 - 57
editor/editor_properties.cpp

@@ -89,8 +89,8 @@ EditorPropertyText::EditorPropertyText() {
 	text = memnew(LineEdit);
 	add_child(text);
 	add_focusable(text);
-	text->connect("text_changed", this, "_text_changed");
-	text->connect("text_entered", this, "_text_entered");
+	text->connect_compat("text_changed", this, "_text_changed");
+	text->connect_compat("text_entered", this, "_text_entered");
 
 	updating = false;
 }
@@ -110,7 +110,7 @@ void EditorPropertyMultilineText::_open_big_text() {
 
 	if (!big_text_dialog) {
 		big_text = memnew(TextEdit);
-		big_text->connect("text_changed", this, "_big_text_changed");
+		big_text->connect_compat("text_changed", this, "_big_text_changed");
 		big_text->set_wrap_enabled(true);
 		big_text_dialog = memnew(AcceptDialog);
 		big_text_dialog->add_child(big_text);
@@ -156,13 +156,13 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() {
 	add_child(hb);
 	set_bottom_editor(hb);
 	text = memnew(TextEdit);
-	text->connect("text_changed", this, "_text_changed");
+	text->connect_compat("text_changed", this, "_text_changed");
 	text->set_wrap_enabled(true);
 	add_focusable(text);
 	hb->add_child(text);
 	text->set_h_size_flags(SIZE_EXPAND_FILL);
 	open_big_text = memnew(ToolButton);
-	open_big_text->connect("pressed", this, "_open_big_text");
+	open_big_text->connect_compat("pressed", this, "_open_big_text");
 	hb->add_child(open_big_text);
 	big_text_dialog = NULL;
 	big_text = NULL;
@@ -205,7 +205,7 @@ EditorPropertyTextEnum::EditorPropertyTextEnum() {
 
 	add_child(options);
 	add_focusable(options);
-	options->connect("item_selected", this, "_option_selected");
+	options->connect_compat("item_selected", this, "_option_selected");
 }
 ///////////////////// PATH /////////////////////////
 
@@ -218,8 +218,8 @@ void EditorPropertyPath::_path_pressed() {
 
 	if (!dialog) {
 		dialog = memnew(EditorFileDialog);
-		dialog->connect("file_selected", this, "_path_selected");
-		dialog->connect("dir_selected", this, "_path_selected");
+		dialog->connect_compat("file_selected", this, "_path_selected");
+		dialog->connect_compat("dir_selected", this, "_path_selected");
 		add_child(dialog);
 	}
 
@@ -293,8 +293,8 @@ EditorPropertyPath::EditorPropertyPath() {
 	add_child(path_hb);
 	path = memnew(LineEdit);
 	path_hb->add_child(path);
-	path->connect("text_entered", this, "_path_selected");
-	path->connect("focus_exited", this, "_path_focus_exited");
+	path->connect_compat("text_entered", this, "_path_selected");
+	path->connect_compat("focus_exited", this, "_path_focus_exited");
 	path->set_h_size_flags(SIZE_EXPAND_FILL);
 
 	path_edit = memnew(Button);
@@ -302,7 +302,7 @@ EditorPropertyPath::EditorPropertyPath() {
 	path_hb->add_child(path_edit);
 	add_focusable(path);
 	dialog = NULL;
-	path_edit->connect("pressed", this, "_path_pressed");
+	path_edit->connect_compat("pressed", this, "_path_pressed");
 	folder = false;
 	global = false;
 	save_mode = false;
@@ -346,10 +346,10 @@ EditorPropertyClassName::EditorPropertyClassName() {
 	add_child(property);
 	add_focusable(property);
 	property->set_text(selected_type);
-	property->connect("pressed", this, "_property_selected");
+	property->connect_compat("pressed", this, "_property_selected");
 	dialog = memnew(CreateDialog);
 	dialog->set_base_type(base_type);
-	dialog->connect("create", this, "_dialog_created");
+	dialog->connect_compat("create", this, "_dialog_created");
 	add_child(dialog);
 }
 
@@ -365,7 +365,7 @@ void EditorPropertyMember::_property_select() {
 
 	if (!selector) {
 		selector = memnew(PropertySelector);
-		selector->connect("selected", this, "_property_selected");
+		selector->connect_compat("selected", this, "_property_selected");
 		add_child(selector);
 	}
 
@@ -455,7 +455,7 @@ EditorPropertyMember::EditorPropertyMember() {
 	property->set_clip_text(true);
 	add_child(property);
 	add_focusable(property);
-	property->connect("pressed", this, "_property_select");
+	property->connect_compat("pressed", this, "_property_select");
 }
 
 ///////////////////// CHECK /////////////////////////
@@ -480,7 +480,7 @@ EditorPropertyCheck::EditorPropertyCheck() {
 	checkbox->set_text(TTR("On"));
 	add_child(checkbox);
 	add_focusable(checkbox);
-	checkbox->connect("pressed", this, "_checkbox_pressed");
+	checkbox->connect_compat("pressed", this, "_checkbox_pressed");
 }
 
 ///////////////////// ENUM /////////////////////////
@@ -531,7 +531,7 @@ EditorPropertyEnum::EditorPropertyEnum() {
 	options->set_flat(true);
 	add_child(options);
 	add_focusable(options);
-	options->connect("item_selected", this, "_option_selected");
+	options->connect_compat("item_selected", this, "_option_selected");
 }
 
 ///////////////////// FLAGS /////////////////////////
@@ -576,7 +576,7 @@ void EditorPropertyFlags::setup(const Vector<String> &p_options) {
 			CheckBox *cb = memnew(CheckBox);
 			cb->set_text(option);
 			cb->set_clip_text(true);
-			cb->connect("pressed", this, "_flag_toggled");
+			cb->connect_compat("pressed", this, "_flag_toggled");
 			add_focusable(cb);
 			vbox->add_child(cb);
 			flags.push_back(cb);
@@ -787,20 +787,20 @@ EditorPropertyLayers::EditorPropertyLayers() {
 	HBoxContainer *hb = memnew(HBoxContainer);
 	add_child(hb);
 	grid = memnew(EditorPropertyLayersGrid);
-	grid->connect("flag_changed", this, "_grid_changed");
+	grid->connect_compat("flag_changed", this, "_grid_changed");
 	grid->set_h_size_flags(SIZE_EXPAND_FILL);
 	hb->add_child(grid);
 	button = memnew(Button);
 	button->set_toggle_mode(true);
 	button->set_text("..");
-	button->connect("pressed", this, "_button_pressed");
+	button->connect_compat("pressed", this, "_button_pressed");
 	hb->add_child(button);
 	set_bottom_editor(hb);
 	layers = memnew(PopupMenu);
 	add_child(layers);
 	layers->set_hide_on_checkable_item_selection(false);
-	layers->connect("id_pressed", this, "_menu_pressed");
-	layers->connect("popup_hide", button, "set_pressed", varray(false));
+	layers->connect_compat("id_pressed", this, "_menu_pressed");
+	layers->connect_compat("popup_hide", button, "set_pressed", varray(false));
 }
 
 ///////////////////// INT /////////////////////////
@@ -841,7 +841,7 @@ EditorPropertyInteger::EditorPropertyInteger() {
 	spin->set_flat(true);
 	add_child(spin);
 	add_focusable(spin);
-	spin->connect("value_changed", this, "_value_changed");
+	spin->connect_compat("value_changed", this, "_value_changed");
 	setting = false;
 }
 
@@ -881,7 +881,7 @@ EditorPropertyObjectID::EditorPropertyObjectID() {
 	edit = memnew(Button);
 	add_child(edit);
 	add_focusable(edit);
-	edit->connect("pressed", this, "_edit_pressed");
+	edit->connect_compat("pressed", this, "_edit_pressed");
 }
 
 ///////////////////// FLOAT /////////////////////////
@@ -921,7 +921,7 @@ EditorPropertyFloat::EditorPropertyFloat() {
 	spin->set_flat(true);
 	add_child(spin);
 	add_focusable(spin);
-	spin->connect("value_changed", this, "_value_changed");
+	spin->connect_compat("value_changed", this, "_value_changed");
 	setting = false;
 }
 
@@ -1100,14 +1100,14 @@ void EditorPropertyEasing::_bind_methods() {
 EditorPropertyEasing::EditorPropertyEasing() {
 
 	easing_draw = memnew(Control);
-	easing_draw->connect("draw", this, "_draw_easing");
-	easing_draw->connect("gui_input", this, "_drag_easing");
+	easing_draw->connect_compat("draw", this, "_draw_easing");
+	easing_draw->connect_compat("gui_input", this, "_drag_easing");
 	easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE);
 	add_child(easing_draw);
 
 	preset = memnew(PopupMenu);
 	add_child(preset);
-	preset->connect("id_pressed", this, "_set_preset");
+	preset->connect_compat("id_pressed", this, "_set_preset");
 
 	spin = memnew(EditorSpinSlider);
 	spin->set_flat(true);
@@ -1117,8 +1117,8 @@ EditorPropertyEasing::EditorPropertyEasing() {
 	spin->set_hide_slider(true);
 	spin->set_allow_lesser(true);
 	spin->set_allow_greater(true);
-	spin->connect("value_changed", this, "_spin_value_changed");
-	spin->get_line_edit()->connect("focus_exited", this, "_spin_focus_exited");
+	spin->connect_compat("value_changed", this, "_spin_value_changed");
+	spin->get_line_edit()->connect_compat("focus_exited", this, "_spin_focus_exited");
 	spin->hide();
 	add_child(spin);
 
@@ -1196,7 +1196,7 @@ EditorPropertyVector2::EditorPropertyVector2() {
 		spin[i]->set_label(desc[i]);
 		bc->add_child(spin[i]);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 		if (horizontal) {
 			spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		}
@@ -1280,7 +1280,7 @@ EditorPropertyRect2::EditorPropertyRect2() {
 		spin[i]->set_flat(true);
 		bc->add_child(spin[i]);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 		if (horizontal) {
 			spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		}
@@ -1361,7 +1361,7 @@ EditorPropertyVector3::EditorPropertyVector3() {
 		spin[i]->set_label(desc[i]);
 		bc->add_child(spin[i]);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 		if (horizontal) {
 			spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		}
@@ -1444,7 +1444,7 @@ EditorPropertyPlane::EditorPropertyPlane() {
 		spin[i]->set_label(desc[i]);
 		bc->add_child(spin[i]);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 		if (horizontal) {
 			spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		}
@@ -1527,7 +1527,7 @@ EditorPropertyQuat::EditorPropertyQuat() {
 		spin[i]->set_label(desc[i]);
 		bc->add_child(spin[i]);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 		if (horizontal) {
 			spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		}
@@ -1609,7 +1609,7 @@ EditorPropertyAABB::EditorPropertyAABB() {
 		g->add_child(spin[i]);
 		spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 	}
 	set_bottom_editor(g);
 	setting = false;
@@ -1684,7 +1684,7 @@ EditorPropertyTransform2D::EditorPropertyTransform2D() {
 		g->add_child(spin[i]);
 		spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 	}
 	set_bottom_editor(g);
 	setting = false;
@@ -1765,7 +1765,7 @@ EditorPropertyBasis::EditorPropertyBasis() {
 		g->add_child(spin[i]);
 		spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 	}
 	set_bottom_editor(g);
 	setting = false;
@@ -1852,7 +1852,7 @@ EditorPropertyTransform::EditorPropertyTransform() {
 		g->add_child(spin[i]);
 		spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
 		add_focusable(spin[i]);
-		spin[i]->connect("value_changed", this, "_value_changed", varray(desc[i]));
+		spin[i]->connect_compat("value_changed", this, "_value_changed", varray(desc[i]));
 	}
 	set_bottom_editor(g);
 	setting = false;
@@ -1917,9 +1917,9 @@ EditorPropertyColor::EditorPropertyColor() {
 	picker = memnew(ColorPickerButton);
 	add_child(picker);
 	picker->set_flat(true);
-	picker->connect("color_changed", this, "_color_changed");
-	picker->connect("popup_closed", this, "_popup_closed");
-	picker->connect("picker_created", this, "_picker_created");
+	picker->connect_compat("color_changed", this, "_color_changed");
+	picker->connect_compat("popup_closed", this, "_popup_closed");
+	picker->connect_compat("picker_created", this, "_picker_created");
 }
 
 ////////////// NODE PATH //////////////////////
@@ -1966,7 +1966,7 @@ void EditorPropertyNodePath::_node_assign() {
 		scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
 		scene_tree->get_scene_tree()->set_valid_types(valid_types);
 		add_child(scene_tree);
-		scene_tree->connect("selected", this, "_node_selected");
+		scene_tree->connect_compat("selected", this, "_node_selected");
 	}
 	scene_tree->popup_centered_ratio();
 }
@@ -2048,12 +2048,12 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
 	assign->set_flat(true);
 	assign->set_h_size_flags(SIZE_EXPAND_FILL);
 	assign->set_clip_text(true);
-	assign->connect("pressed", this, "_node_assign");
+	assign->connect_compat("pressed", this, "_node_assign");
 	hbc->add_child(assign);
 
 	clear = memnew(Button);
 	clear->set_flat(true);
-	clear->connect("pressed", this, "_node_clear");
+	clear->connect_compat("pressed", this, "_node_clear");
 	hbc->add_child(clear);
 	use_path_from_scene_root = false;
 
@@ -2120,7 +2120,7 @@ void EditorPropertyResource::_menu_option(int p_which) {
 
 			if (!file) {
 				file = memnew(EditorFileDialog);
-				file->connect("file_selected", this, "_file_selected");
+				file->connect_compat("file_selected", this, "_file_selected");
 				add_child(file);
 			}
 			file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -2289,7 +2289,7 @@ void EditorPropertyResource::_menu_option(int p_which) {
 					scene_tree->get_scene_tree()->set_valid_types(valid_types);
 					scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
 					add_child(scene_tree);
-					scene_tree->connect("selected", this, "_viewport_selected");
+					scene_tree->connect_compat("selected", this, "_viewport_selected");
 					scene_tree->set_title(TTR("Pick a Viewport"));
 				}
 				scene_tree->popup_centered_ratio();
@@ -2607,9 +2607,9 @@ void EditorPropertyResource::update_property() {
 				sub_inspector->set_sub_inspector(true);
 				sub_inspector->set_enable_capitalize_paths(true);
 
-				sub_inspector->connect("property_keyed", this, "_sub_inspector_property_keyed");
-				sub_inspector->connect("resource_selected", this, "_sub_inspector_resource_selected");
-				sub_inspector->connect("object_id_selected", this, "_sub_inspector_object_id_selected");
+				sub_inspector->connect_compat("property_keyed", this, "_sub_inspector_property_keyed");
+				sub_inspector->connect_compat("resource_selected", this, "_sub_inspector_resource_selected");
+				sub_inspector->connect_compat("object_id_selected", this, "_sub_inspector_object_id_selected");
 				sub_inspector->set_keying(is_keying());
 				sub_inspector->set_read_only(is_read_only());
 				sub_inspector->set_use_folding(is_using_folding());
@@ -2892,9 +2892,9 @@ EditorPropertyResource::EditorPropertyResource() {
 	assign->set_flat(true);
 	assign->set_h_size_flags(SIZE_EXPAND_FILL);
 	assign->set_clip_text(true);
-	assign->connect("pressed", this, "_resource_selected");
+	assign->connect_compat("pressed", this, "_resource_selected");
 	assign->set_drag_forwarding(this);
-	assign->connect("draw", this, "_button_draw");
+	assign->connect_compat("draw", this, "_button_draw");
 	hbc->add_child(assign);
 	add_focusable(assign);
 
@@ -2905,18 +2905,18 @@ EditorPropertyResource::EditorPropertyResource() {
 	preview->set_margin(MARGIN_BOTTOM, -1);
 	preview->set_margin(MARGIN_RIGHT, -1);
 	assign->add_child(preview);
-	assign->connect("gui_input", this, "_button_input");
+	assign->connect_compat("gui_input", this, "_button_input");
 
 	menu = memnew(PopupMenu);
 	add_child(menu);
 	edit = memnew(Button);
 	edit->set_flat(true);
 	edit->set_toggle_mode(true);
-	menu->connect("id_pressed", this, "_menu_option");
-	menu->connect("popup_hide", edit, "set_pressed", varray(false));
-	edit->connect("pressed", this, "_update_menu");
+	menu->connect_compat("id_pressed", this, "_menu_option");
+	menu->connect_compat("popup_hide", edit, "set_pressed", varray(false));
+	edit->connect_compat("pressed", this, "_update_menu");
 	hbc->add_child(edit);
-	edit->connect("gui_input", this, "_button_input");
+	edit->connect_compat("gui_input", this, "_button_input");
 	add_focusable(edit);
 
 	file = NULL;

+ 22 - 22
editor/editor_properties_array_dict.cpp

@@ -198,7 +198,7 @@ void EditorPropertyArray::_change_type_menu(int p_index) {
 	}
 
 	Variant value;
-	Variant::CallError ce;
+	Callable::CallError ce;
 	value = Variant::construct(Variant::Type(p_index), NULL, 0, ce);
 	Variant array = object->get_array();
 	array.set(changing_type_idx, value);
@@ -290,7 +290,7 @@ void EditorPropertyArray::update_property() {
 			length->set_max(1000000);
 			length->set_h_size_flags(SIZE_EXPAND_FILL);
 			hbc->add_child(length);
-			length->connect("value_changed", this, "_length_changed");
+			length->connect_compat("value_changed", this, "_length_changed");
 
 			page_hb = memnew(HBoxContainer);
 			vbox->add_child(page_hb);
@@ -301,7 +301,7 @@ void EditorPropertyArray::update_property() {
 			page->set_step(1);
 			page_hb->add_child(page);
 			page->set_h_size_flags(SIZE_EXPAND_FILL);
-			page->connect("value_changed", this, "_page_changed");
+			page->connect_compat("value_changed", this, "_page_changed");
 		} else {
 			//bye bye children of the box
 			while (vbox->get_child_count() > 2) {
@@ -353,8 +353,8 @@ void EditorPropertyArray::update_property() {
 			prop->set_object_and_property(object.ptr(), prop_name);
 			prop->set_label(itos(i + offset));
 			prop->set_selectable(false);
-			prop->connect("property_changed", this, "_property_changed");
-			prop->connect("object_id_selected", this, "_object_id_selected");
+			prop->connect_compat("property_changed", this, "_property_changed");
+			prop->connect_compat("object_id_selected", this, "_object_id_selected");
 			prop->set_h_size_flags(SIZE_EXPAND_FILL);
 
 			HBoxContainer *hb = memnew(HBoxContainer);
@@ -369,12 +369,12 @@ void EditorPropertyArray::update_property() {
 				Button *edit = memnew(Button);
 				edit->set_icon(get_icon("Edit", "EditorIcons"));
 				hb->add_child(edit);
-				edit->connect("pressed", this, "_change_type", varray(edit, i + offset));
+				edit->connect_compat("pressed", this, "_change_type", varray(edit, i + offset));
 			} else {
 
 				Button *remove = memnew(Button);
 				remove->set_icon(get_icon("Remove", "EditorIcons"));
-				remove->connect("pressed", this, "_remove_pressed", varray(i + offset));
+				remove->connect_compat("pressed", this, "_remove_pressed", varray(i + offset));
 				hb->add_child(remove);
 			}
 
@@ -412,7 +412,7 @@ void EditorPropertyArray::_edit_pressed() {
 
 	Variant array = get_edited_object()->get(get_edited_property());
 	if (!array.is_array()) {
-		Variant::CallError ce;
+		Callable::CallError ce;
 		array = Variant::construct(array_type, NULL, 0, ce);
 
 		get_edited_object()->set(get_edited_property(), array);
@@ -443,7 +443,7 @@ void EditorPropertyArray::_length_changed(double p_page) {
 			int size = array.call("size");
 			for (int i = previous_size; i < size; i++) {
 				if (array.get(i).get_type() == Variant::NIL) {
-					Variant::CallError ce;
+					Callable::CallError ce;
 					array.set(i, Variant::construct(subtype, NULL, 0, ce));
 				}
 			}
@@ -453,7 +453,7 @@ void EditorPropertyArray::_length_changed(double p_page) {
 		int size = array.call("size");
 		// Pool*Array don't initialize their elements, have to do it manually
 		for (int i = previous_size; i < size; i++) {
-			Variant::CallError ce;
+			Callable::CallError ce;
 			array.set(i, Variant::construct(array.get(i).get_type(), NULL, 0, ce));
 		}
 	}
@@ -503,7 +503,7 @@ EditorPropertyArray::EditorPropertyArray() {
 	edit->set_flat(true);
 	edit->set_h_size_flags(SIZE_EXPAND_FILL);
 	edit->set_clip_text(true);
-	edit->connect("pressed", this, "_edit_pressed");
+	edit->connect_compat("pressed", this, "_edit_pressed");
 	edit->set_toggle_mode(true);
 	add_child(edit);
 	add_focusable(edit);
@@ -513,7 +513,7 @@ EditorPropertyArray::EditorPropertyArray() {
 	updating = false;
 	change_type = memnew(PopupMenu);
 	add_child(change_type);
-	change_type->connect("id_pressed", this, "_change_type_menu");
+	change_type->connect_compat("id_pressed", this, "_change_type_menu");
 
 	for (int i = 0; i < Variant::VARIANT_MAX; i++) {
 		String type = Variant::get_type_name(Variant::Type(i));
@@ -586,7 +586,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
 
 	if (changing_type_idx < 0) {
 		Variant value;
-		Variant::CallError ce;
+		Callable::CallError ce;
 		value = Variant::construct(Variant::Type(p_index), NULL, 0, ce);
 		if (changing_type_idx == -1) {
 			object->set_new_item_key(value);
@@ -602,7 +602,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
 	if (p_index < Variant::VARIANT_MAX) {
 
 		Variant value;
-		Variant::CallError ce;
+		Callable::CallError ce;
 		value = Variant::construct(Variant::Type(p_index), NULL, 0, ce);
 		Variant key = dict.get_key_at_index(changing_type_idx);
 		dict[key] = value;
@@ -661,7 +661,7 @@ void EditorPropertyDictionary::update_property() {
 			page->set_step(1);
 			page_hb->add_child(page);
 			page->set_h_size_flags(SIZE_EXPAND_FILL);
-			page->connect("value_changed", this, "_page_changed");
+			page->connect_compat("value_changed", this, "_page_changed");
 		} else {
 			// Queue children for deletion, deleting immediately might cause errors.
 			for (int i = 1; i < vbox->get_child_count(); i++) {
@@ -916,8 +916,8 @@ void EditorPropertyDictionary::update_property() {
 			}
 
 			prop->set_selectable(false);
-			prop->connect("property_changed", this, "_property_changed");
-			prop->connect("object_id_selected", this, "_object_id_selected");
+			prop->connect_compat("property_changed", this, "_property_changed");
+			prop->connect_compat("object_id_selected", this, "_object_id_selected");
 
 			HBoxContainer *hb = memnew(HBoxContainer);
 			if (add_vbox) {
@@ -930,14 +930,14 @@ void EditorPropertyDictionary::update_property() {
 			Button *edit = memnew(Button);
 			edit->set_icon(get_icon("Edit", "EditorIcons"));
 			hb->add_child(edit);
-			edit->connect("pressed", this, "_change_type", varray(edit, change_index));
+			edit->connect_compat("pressed", this, "_change_type", varray(edit, change_index));
 
 			prop->update_property();
 
 			if (i == amount + 1) {
 				Button *butt_add_item = memnew(Button);
 				butt_add_item->set_text(TTR("Add Key/Value Pair"));
-				butt_add_item->connect("pressed", this, "_add_key_value");
+				butt_add_item->connect_compat("pressed", this, "_add_key_value");
 				add_vbox->add_child(butt_add_item);
 			}
 		}
@@ -964,7 +964,7 @@ void EditorPropertyDictionary::_edit_pressed() {
 
 	Variant prop_val = get_edited_object()->get(get_edited_property());
 	if (prop_val.get_type() == Variant::NIL) {
-		Variant::CallError ce;
+		Callable::CallError ce;
 		prop_val = Variant::construct(Variant::DICTIONARY, NULL, 0, ce);
 		get_edited_object()->set(get_edited_property(), prop_val);
 	}
@@ -999,7 +999,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
 	edit->set_flat(true);
 	edit->set_h_size_flags(SIZE_EXPAND_FILL);
 	edit->set_clip_text(true);
-	edit->connect("pressed", this, "_edit_pressed");
+	edit->connect_compat("pressed", this, "_edit_pressed");
 	edit->set_toggle_mode(true);
 	add_child(edit);
 	add_focusable(edit);
@@ -1008,7 +1008,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
 	updating = false;
 	change_type = memnew(PopupMenu);
 	add_child(change_type);
-	change_type->connect("id_pressed", this, "_change_type_menu");
+	change_type->connect_compat("id_pressed", this, "_change_type_menu");
 
 	for (int i = 0; i < Variant::VARIANT_MAX; i++) {
 		String type = Variant::get_type_name(Variant::Type(i));

+ 2 - 2
editor/editor_run_native.cpp

@@ -55,8 +55,8 @@ void EditorRunNative::_notification(int p_what) {
 					small_icon.instance();
 					small_icon->create_from_image(im);
 					MenuButton *mb = memnew(MenuButton);
-					mb->get_popup()->connect("id_pressed", this, "_run_native", varray(i));
-					mb->connect("pressed", this, "_run_native", varray(-1, i));
+					mb->get_popup()->connect_compat("id_pressed", this, "_run_native", varray(i));
+					mb->connect_compat("pressed", this, "_run_native", varray(-1, i));
 					mb->set_icon(small_icon);
 					add_child(mb);
 					menus[i] = mb;

+ 3 - 3
editor/editor_run_script.cpp

@@ -71,10 +71,10 @@ void EditorScript::_run() {
 		return;
 	}
 
-	Variant::CallError ce;
-	ce.error = Variant::CallError::CALL_OK;
+	Callable::CallError ce;
+	ce.error = Callable::CallError::CALL_OK;
 	get_script_instance()->call("_run", NULL, 0, ce);
-	if (ce.error != Variant::CallError::CALL_OK) {
+	if (ce.error != Callable::CallError::CALL_OK) {
 
 		EditorNode::add_io_error(TTR("Couldn't run script:") + "\n " + s->get_path() + "\n" + TTR("Did you forget the '_run' method?"));
 	}

+ 2 - 2
editor/editor_sectioned_inspector.cpp

@@ -294,7 +294,7 @@ void SectionedInspector::register_search_box(LineEdit *p_box) {
 
 	search_box = p_box;
 	inspector->register_text_enter(p_box);
-	search_box->connect("text_changed", this, "_search_changed");
+	search_box->connect_compat("text_changed", this, "_search_changed");
 }
 
 void SectionedInspector::_search_changed(const String &p_what) {
@@ -332,7 +332,7 @@ SectionedInspector::SectionedInspector() :
 	right_vb->add_child(inspector, true);
 	inspector->set_use_doc_hints(true);
 
-	sections->connect("cell_selected", this, "_section_selected");
+	sections->connect_compat("cell_selected", this, "_section_selected");
 }
 
 SectionedInspector::~SectionedInspector() {

+ 6 - 6
editor/editor_spin_slider.cpp

@@ -490,9 +490,9 @@ EditorSpinSlider::EditorSpinSlider() {
 	grabber->hide();
 	grabber->set_as_toplevel(true);
 	grabber->set_mouse_filter(MOUSE_FILTER_STOP);
-	grabber->connect("mouse_entered", this, "_grabber_mouse_entered");
-	grabber->connect("mouse_exited", this, "_grabber_mouse_exited");
-	grabber->connect("gui_input", this, "_grabber_gui_input");
+	grabber->connect_compat("mouse_entered", this, "_grabber_mouse_entered");
+	grabber->connect_compat("mouse_exited", this, "_grabber_mouse_exited");
+	grabber->connect_compat("gui_input", this, "_grabber_gui_input");
 	mouse_over_spin = false;
 	mouse_over_grabber = false;
 	mousewheel_over_grabber = false;
@@ -502,9 +502,9 @@ EditorSpinSlider::EditorSpinSlider() {
 	add_child(value_input);
 	value_input->set_as_toplevel(true);
 	value_input->hide();
-	value_input->connect("modal_closed", this, "_value_input_closed");
-	value_input->connect("text_entered", this, "_value_input_entered");
-	value_input->connect("focus_exited", this, "_value_focus_exited");
+	value_input->connect_compat("modal_closed", this, "_value_input_closed");
+	value_input->connect_compat("text_entered", this, "_value_input_entered");
+	value_input->connect_compat("focus_exited", this, "_value_focus_exited");
 	value_input_just_closed = false;
 	hide_slider = false;
 	read_only = false;

+ 6 - 6
editor/editor_sub_scene.cpp

@@ -239,24 +239,24 @@ EditorSubScene::EditorSubScene() {
 
 	HBoxContainer *hb = memnew(HBoxContainer);
 	path = memnew(LineEdit);
-	path->connect("text_entered", this, "_path_changed");
+	path->connect_compat("text_entered", this, "_path_changed");
 	hb->add_child(path);
 	path->set_h_size_flags(SIZE_EXPAND_FILL);
 	Button *b = memnew(Button);
 	b->set_text(TTR("Browse"));
 	hb->add_child(b);
-	b->connect("pressed", this, "_path_browse");
+	b->connect_compat("pressed", this, "_path_browse");
 	vb->add_margin_child(TTR("Scene Path:"), hb);
 
 	tree = memnew(Tree);
 	tree->set_v_size_flags(SIZE_EXPAND_FILL);
 	vb->add_margin_child(TTR("Import From Node:"), tree, true);
 	tree->set_select_mode(Tree::SELECT_MULTI);
-	tree->connect("multi_selected", this, "_item_multi_selected");
+	tree->connect_compat("multi_selected", this, "_item_multi_selected");
 	//tree->connect("nothing_selected", this, "_deselect_items");
-	tree->connect("cell_selected", this, "_selected_changed");
+	tree->connect_compat("cell_selected", this, "_selected_changed");
 
-	tree->connect("item_activated", this, "_ok", make_binds(), CONNECT_DEFERRED);
+	tree->connect_compat("item_activated", this, "_ok", make_binds(), CONNECT_DEFERRED);
 
 	file_dialog = memnew(EditorFileDialog);
 	List<String> extensions;
@@ -269,5 +269,5 @@ EditorSubScene::EditorSubScene() {
 
 	file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
 	add_child(file_dialog);
-	file_dialog->connect("file_selected", this, "_path_selected");
+	file_dialog->connect_compat("file_selected", this, "_path_selected");
 }

+ 12 - 12
editor/editor_visual_profiler.cpp

@@ -753,12 +753,12 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	activate = memnew(Button);
 	activate->set_toggle_mode(true);
 	activate->set_text(TTR("Start"));
-	activate->connect("pressed", this, "_activate_pressed");
+	activate->connect_compat("pressed", this, "_activate_pressed");
 	hb->add_child(activate);
 
 	clear_button = memnew(Button);
 	clear_button->set_text(TTR("Clear"));
-	clear_button->connect("pressed", this, "_clear_pressed");
+	clear_button->connect_compat("pressed", this, "_clear_pressed");
 	hb->add_child(clear_button);
 
 	hb->add_child(memnew(Label(TTR("Measure:"))));
@@ -766,18 +766,18 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	display_mode = memnew(OptionButton);
 	display_mode->add_item(TTR("Frame Time (msec)"));
 	display_mode->add_item(TTR("Frame %"));
-	display_mode->connect("item_selected", this, "_combo_changed");
+	display_mode->connect_compat("item_selected", this, "_combo_changed");
 
 	hb->add_child(display_mode);
 
 	frame_relative = memnew(CheckBox(TTR("Fit to Frame")));
 	frame_relative->set_pressed(true);
 	hb->add_child(frame_relative);
-	frame_relative->connect("pressed", this, "_update_plot");
+	frame_relative->connect_compat("pressed", this, "_update_plot");
 	linked = memnew(CheckBox(TTR("Linked")));
 	linked->set_pressed(true);
 	hb->add_child(linked);
-	linked->connect("pressed", this, "_update_plot");
+	linked->connect_compat("pressed", this, "_update_plot");
 
 	hb->add_spacer();
 
@@ -786,7 +786,7 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	cursor_metric_edit = memnew(SpinBox);
 	cursor_metric_edit->set_h_size_flags(SIZE_FILL);
 	hb->add_child(cursor_metric_edit);
-	cursor_metric_edit->connect("value_changed", this, "_cursor_metric_changed");
+	cursor_metric_edit->connect_compat("value_changed", this, "_cursor_metric_changed");
 
 	hb->add_constant_override("separation", 8 * EDSCALE);
 
@@ -810,15 +810,15 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	variables->set_column_title(2, TTR("GPU"));
 	variables->set_column_expand(2, false);
 	variables->set_column_min_width(2, 60 * EDSCALE);
-	variables->connect("cell_selected", this, "_item_selected");
+	variables->connect_compat("cell_selected", this, "_item_selected");
 
 	graph = memnew(TextureRect);
 	graph->set_expand(true);
 	graph->set_mouse_filter(MOUSE_FILTER_STOP);
 	//graph->set_ignore_mouse(false);
-	graph->connect("draw", this, "_graph_tex_draw");
-	graph->connect("gui_input", this, "_graph_tex_input");
-	graph->connect("mouse_exited", this, "_graph_tex_mouse_exit");
+	graph->connect_compat("draw", this, "_graph_tex_draw");
+	graph->connect_compat("gui_input", this, "_graph_tex_input");
+	graph->connect_compat("mouse_exited", this, "_graph_tex_mouse_exit");
 
 	h_split->add_child(graph);
 	graph->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -835,13 +835,13 @@ EditorVisualProfiler::EditorVisualProfiler() {
 	frame_delay->set_wait_time(0.1);
 	frame_delay->set_one_shot(true);
 	add_child(frame_delay);
-	frame_delay->connect("timeout", this, "_update_frame");
+	frame_delay->connect_compat("timeout", this, "_update_frame");
 
 	plot_delay = memnew(Timer);
 	plot_delay->set_wait_time(0.1);
 	plot_delay->set_one_shot(true);
 	add_child(plot_delay);
-	plot_delay->connect("timeout", this, "_update_plot");
+	plot_delay->connect_compat("timeout", this, "_update_plot");
 
 	seeking = false;
 	graph_height_cpu = 1;

+ 10 - 10
editor/export_template_manager.cpp

@@ -93,14 +93,14 @@ void ExportTemplateManager::_update_template_list() {
 			Button *redownload = memnew(Button);
 			redownload->set_text(TTR("Redownload"));
 			current_hb->add_child(redownload);
-			redownload->connect("pressed", this, "_download_template", varray(current_version));
+			redownload->connect_compat("pressed", this, "_download_template", varray(current_version));
 		}
 
 		Button *uninstall = memnew(Button);
 		uninstall->set_text(TTR("Uninstall"));
 		current_hb->add_child(uninstall);
 		current->set_text(current_version + " " + TTR("(Installed)"));
-		uninstall->connect("pressed", this, "_uninstall_template", varray(current_version));
+		uninstall->connect_compat("pressed", this, "_uninstall_template", varray(current_version));
 
 	} else {
 		current->add_color_override("font_color", get_color("error_color", "Editor"));
@@ -112,7 +112,7 @@ void ExportTemplateManager::_update_template_list() {
 			redownload->set_tooltip(TTR("Official export templates aren't available for development builds."));
 		}
 
-		redownload->connect("pressed", this, "_download_template", varray(current_version));
+		redownload->connect_compat("pressed", this, "_download_template", varray(current_version));
 		current_hb->add_child(redownload);
 		current->set_text(current_version + " " + TTR("(Missing)"));
 	}
@@ -134,7 +134,7 @@ void ExportTemplateManager::_update_template_list() {
 
 		uninstall->set_text(TTR("Uninstall"));
 		hbc->add_child(uninstall);
-		uninstall->connect("pressed", this, "_uninstall_template", varray(E->get()));
+		uninstall->connect_compat("pressed", this, "_uninstall_template", varray(E->get()));
 
 		installed_vb->add_child(hbc);
 	}
@@ -385,7 +385,7 @@ void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_
 			ERR_CONTINUE(!m.has("url") || !m.has("name"));
 			LinkButton *lb = memnew(LinkButton);
 			lb->set_text(m["name"]);
-			lb->connect("pressed", this, "_begin_template_download", varray(m["url"]));
+			lb->connect_compat("pressed", this, "_begin_template_download", varray(m["url"]));
 			template_list->add_child(lb);
 			mirrors_found = true;
 		}
@@ -689,14 +689,14 @@ ExportTemplateManager::ExportTemplateManager() {
 	remove_confirm = memnew(ConfirmationDialog);
 	remove_confirm->set_title(TTR("Remove Template"));
 	add_child(remove_confirm);
-	remove_confirm->connect("confirmed", this, "_uninstall_template_confirm");
+	remove_confirm->connect_compat("confirmed", this, "_uninstall_template_confirm");
 
 	template_open = memnew(FileDialog);
 	template_open->set_title(TTR("Select Template File"));
 	template_open->add_filter("*.tpz ; " + TTR("Godot Export Templates"));
 	template_open->set_access(FileDialog::ACCESS_FILESYSTEM);
 	template_open->set_mode(FileDialog::MODE_OPEN_FILE);
-	template_open->connect("file_selected", this, "_install_from_file", varray(true));
+	template_open->connect_compat("file_selected", this, "_install_from_file", varray(true));
 	add_child(template_open);
 
 	set_title(TTR("Export Template Manager"));
@@ -704,18 +704,18 @@ ExportTemplateManager::ExportTemplateManager() {
 
 	request_mirror = memnew(HTTPRequest);
 	add_child(request_mirror);
-	request_mirror->connect("request_completed", this, "_http_download_mirror_completed");
+	request_mirror->connect_compat("request_completed", this, "_http_download_mirror_completed");
 
 	download_templates = memnew(HTTPRequest);
 	add_child(download_templates);
-	download_templates->connect("request_completed", this, "_http_download_templates_completed");
+	download_templates->connect_compat("request_completed", this, "_http_download_templates_completed");
 
 	template_downloader = memnew(AcceptDialog);
 	template_downloader->set_title(TTR("Download Templates"));
 	template_downloader->get_ok()->set_text(TTR("Close"));
 	template_downloader->set_exclusive(true);
 	add_child(template_downloader);
-	template_downloader->connect("popup_hide", this, "_window_template_downloader_closed");
+	template_downloader->connect_compat("popup_hide", this, "_window_template_downloader_closed");
 
 	VBoxContainer *vbc = memnew(VBoxContainer);
 	template_downloader->add_child(vbc);

+ 33 - 33
editor/filesystem_dock.cpp

@@ -300,19 +300,19 @@ void FileSystemDock::_notification(int p_what) {
 			if (initialized)
 				return;
 			initialized = true;
-			EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", this, "_feature_profile_changed");
+			EditorFeatureProfileManager::get_singleton()->connect_compat("current_feature_profile_changed", this, "_feature_profile_changed");
 
-			EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed");
-			EditorResourcePreview::get_singleton()->connect("preview_invalidated", this, "_preview_invalidated");
+			EditorFileSystem::get_singleton()->connect_compat("filesystem_changed", this, "_fs_changed");
+			EditorResourcePreview::get_singleton()->connect_compat("preview_invalidated", this, "_preview_invalidated");
 
 			String ei = "EditorIcons";
 			button_reload->set_icon(get_icon("Reload", ei));
 			button_toggle_display_mode->set_icon(get_icon("Panels2", ei));
-			button_file_list_display_mode->connect("pressed", this, "_toggle_file_display");
+			button_file_list_display_mode->connect_compat("pressed", this, "_toggle_file_display");
 
-			files->connect("item_activated", this, "_file_list_activate_file");
-			button_hist_next->connect("pressed", this, "_fw_history");
-			button_hist_prev->connect("pressed", this, "_bw_history");
+			files->connect_compat("item_activated", this, "_file_list_activate_file");
+			button_hist_next->connect_compat("pressed", this, "_fw_history");
+			button_hist_prev->connect_compat("pressed", this, "_bw_history");
 			tree_search_box->set_right_icon(get_icon("Search", ei));
 			tree_search_box->set_clear_button_enabled(true);
 			file_list_search_box->set_right_icon(get_icon("Search", ei));
@@ -320,10 +320,10 @@ void FileSystemDock::_notification(int p_what) {
 
 			button_hist_next->set_icon(get_icon("Forward", ei));
 			button_hist_prev->set_icon(get_icon("Back", ei));
-			file_list_popup->connect("id_pressed", this, "_file_list_rmb_option");
-			tree_popup->connect("id_pressed", this, "_tree_rmb_option");
+			file_list_popup->connect_compat("id_pressed", this, "_file_list_rmb_option");
+			tree_popup->connect_compat("id_pressed", this, "_tree_rmb_option");
 
-			current_path->connect("text_entered", this, "_navigate_to_path");
+			current_path->connect_compat("text_entered", this, "_navigate_to_path");
 
 			always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders"));
 
@@ -2552,7 +2552,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 
 	button_reload = memnew(Button);
 	button_reload->set_flat(true);
-	button_reload->connect("pressed", this, "_rescan");
+	button_reload->connect_compat("pressed", this, "_rescan");
 	button_reload->set_focus_mode(FOCUS_NONE);
 	button_reload->set_tooltip(TTR("Re-Scan Filesystem"));
 	button_reload->hide();
@@ -2561,7 +2561,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	button_toggle_display_mode = memnew(Button);
 	button_toggle_display_mode->set_flat(true);
 	button_toggle_display_mode->set_toggle_mode(true);
-	button_toggle_display_mode->connect("toggled", this, "_toggle_split_mode");
+	button_toggle_display_mode->connect_compat("toggled", this, "_toggle_split_mode");
 	button_toggle_display_mode->set_focus_mode(FOCUS_NONE);
 	button_toggle_display_mode->set_tooltip(TTR("Toggle Split Mode"));
 	toolbar_hbc->add_child(button_toggle_display_mode);
@@ -2573,7 +2573,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	tree_search_box = memnew(LineEdit);
 	tree_search_box->set_h_size_flags(SIZE_EXPAND_FILL);
 	tree_search_box->set_placeholder(TTR("Search files"));
-	tree_search_box->connect("text_changed", this, "_search_changed", varray(tree_search_box));
+	tree_search_box->connect_compat("text_changed", this, "_search_changed", varray(tree_search_box));
 	toolbar2_hbc->add_child(tree_search_box);
 
 	file_list_popup = memnew(PopupMenu);
@@ -2597,12 +2597,12 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE));
 	split_box->add_child(tree);
 
-	tree->connect("item_activated", this, "_tree_activate_file");
-	tree->connect("multi_selected", this, "_tree_multi_selected");
-	tree->connect("item_rmb_selected", this, "_tree_rmb_select");
-	tree->connect("empty_rmb", this, "_tree_rmb_empty");
-	tree->connect("nothing_selected", this, "_tree_empty_selected");
-	tree->connect("gui_input", this, "_tree_gui_input");
+	tree->connect_compat("item_activated", this, "_tree_activate_file");
+	tree->connect_compat("multi_selected", this, "_tree_multi_selected");
+	tree->connect_compat("item_rmb_selected", this, "_tree_rmb_select");
+	tree->connect_compat("empty_rmb", this, "_tree_rmb_empty");
+	tree->connect_compat("nothing_selected", this, "_tree_empty_selected");
+	tree->connect_compat("gui_input", this, "_tree_gui_input");
 
 	file_list_vb = memnew(VBoxContainer);
 	file_list_vb->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -2614,7 +2614,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	file_list_search_box = memnew(LineEdit);
 	file_list_search_box->set_h_size_flags(SIZE_EXPAND_FILL);
 	file_list_search_box->set_placeholder(TTR("Search files"));
-	file_list_search_box->connect("text_changed", this, "_search_changed", varray(file_list_search_box));
+	file_list_search_box->connect_compat("text_changed", this, "_search_changed", varray(file_list_search_box));
 	path_hb->add_child(file_list_search_box);
 
 	button_file_list_display_mode = memnew(ToolButton);
@@ -2624,10 +2624,10 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	files->set_v_size_flags(SIZE_EXPAND_FILL);
 	files->set_select_mode(ItemList::SELECT_MULTI);
 	files->set_drag_forwarding(this);
-	files->connect("item_rmb_selected", this, "_file_list_rmb_select");
-	files->connect("gui_input", this, "_file_list_gui_input");
-	files->connect("multi_selected", this, "_file_multi_selected");
-	files->connect("rmb_clicked", this, "_file_list_rmb_pressed");
+	files->connect_compat("item_rmb_selected", this, "_file_list_rmb_select");
+	files->connect_compat("gui_input", this, "_file_list_gui_input");
+	files->connect_compat("multi_selected", this, "_file_multi_selected");
+	files->connect_compat("rmb_clicked", this, "_file_list_rmb_pressed");
 	files->set_custom_minimum_size(Size2(0, 15 * EDSCALE));
 	files->set_allow_rmb_select(true);
 	file_list_vb->add_child(files);
@@ -2651,14 +2651,14 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	add_child(owners_editor);
 
 	remove_dialog = memnew(DependencyRemoveDialog);
-	remove_dialog->connect("file_removed", this, "_file_deleted");
-	remove_dialog->connect("folder_removed", this, "_folder_deleted");
+	remove_dialog->connect_compat("file_removed", this, "_file_deleted");
+	remove_dialog->connect_compat("folder_removed", this, "_folder_deleted");
 	add_child(remove_dialog);
 
 	move_dialog = memnew(EditorDirDialog);
 	move_dialog->get_ok()->set_text(TTR("Move"));
 	add_child(move_dialog);
-	move_dialog->connect("dir_selected", this, "_move_operation_confirm");
+	move_dialog->connect_compat("dir_selected", this, "_move_operation_confirm");
 
 	rename_dialog = memnew(ConfirmationDialog);
 	VBoxContainer *rename_dialog_vb = memnew(VBoxContainer);
@@ -2669,13 +2669,13 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	rename_dialog->get_ok()->set_text(TTR("Rename"));
 	add_child(rename_dialog);
 	rename_dialog->register_text_enter(rename_dialog_text);
-	rename_dialog->connect("confirmed", this, "_rename_operation_confirm");
+	rename_dialog->connect_compat("confirmed", this, "_rename_operation_confirm");
 
 	overwrite_dialog = memnew(ConfirmationDialog);
 	overwrite_dialog->set_text(TTR("There is already file or folder with the same name in this location."));
 	overwrite_dialog->get_ok()->set_text(TTR("Overwrite"));
 	add_child(overwrite_dialog);
-	overwrite_dialog->connect("confirmed", this, "_move_with_overwrite");
+	overwrite_dialog->connect_compat("confirmed", this, "_move_with_overwrite");
 
 	duplicate_dialog = memnew(ConfirmationDialog);
 	VBoxContainer *duplicate_dialog_vb = memnew(VBoxContainer);
@@ -2686,7 +2686,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	duplicate_dialog->get_ok()->set_text(TTR("Duplicate"));
 	add_child(duplicate_dialog);
 	duplicate_dialog->register_text_enter(duplicate_dialog_text);
-	duplicate_dialog->connect("confirmed", this, "_duplicate_operation_confirm");
+	duplicate_dialog->connect_compat("confirmed", this, "_duplicate_operation_confirm");
 
 	make_dir_dialog = memnew(ConfirmationDialog);
 	make_dir_dialog->set_title(TTR("Create Folder"));
@@ -2697,7 +2697,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	make_folder_dialog_vb->add_margin_child(TTR("Name:"), make_dir_dialog_text);
 	add_child(make_dir_dialog);
 	make_dir_dialog->register_text_enter(make_dir_dialog_text);
-	make_dir_dialog->connect("confirmed", this, "_make_dir_confirm");
+	make_dir_dialog->connect_compat("confirmed", this, "_make_dir_confirm");
 
 	make_scene_dialog = memnew(ConfirmationDialog);
 	make_scene_dialog->set_title(TTR("Create Scene"));
@@ -2708,7 +2708,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	make_scene_dialog_vb->add_margin_child(TTR("Name:"), make_scene_dialog_text);
 	add_child(make_scene_dialog);
 	make_scene_dialog->register_text_enter(make_scene_dialog_text);
-	make_scene_dialog->connect("confirmed", this, "_make_scene_confirm");
+	make_scene_dialog->connect_compat("confirmed", this, "_make_scene_confirm");
 
 	make_script_dialog = memnew(ScriptCreateDialog);
 	make_script_dialog->set_title(TTR("Create Script"));
@@ -2717,7 +2717,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
 	new_resource_dialog = memnew(CreateDialog);
 	add_child(new_resource_dialog);
 	new_resource_dialog->set_base_type("Resource");
-	new_resource_dialog->connect("create", this, "_resource_created");
+	new_resource_dialog->connect_compat("create", this, "_resource_created");
 
 	searched_string = String();
 	uncollapsed_paths_before_search = Vector<String>();

+ 12 - 12
editor/find_in_files.cpp

@@ -319,8 +319,8 @@ FindInFilesDialog::FindInFilesDialog() {
 
 	_search_text_line_edit = memnew(LineEdit);
 	_search_text_line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
-	_search_text_line_edit->connect("text_changed", this, "_on_search_text_modified");
-	_search_text_line_edit->connect("text_entered", this, "_on_search_text_entered");
+	_search_text_line_edit->connect_compat("text_changed", this, "_on_search_text_modified");
+	_search_text_line_edit->connect_compat("text_entered", this, "_on_search_text_entered");
 	gc->add_child(_search_text_line_edit);
 
 	_replace_label = memnew(Label);
@@ -330,7 +330,7 @@ FindInFilesDialog::FindInFilesDialog() {
 
 	_replace_text_line_edit = memnew(LineEdit);
 	_replace_text_line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
-	_replace_text_line_edit->connect("text_entered", this, "_on_replace_text_entered");
+	_replace_text_line_edit->connect_compat("text_entered", this, "_on_replace_text_entered");
 	_replace_text_line_edit->hide();
 	gc->add_child(_replace_text_line_edit);
 
@@ -367,12 +367,12 @@ FindInFilesDialog::FindInFilesDialog() {
 
 		Button *folder_button = memnew(Button);
 		folder_button->set_text("...");
-		folder_button->connect("pressed", this, "_on_folder_button_pressed");
+		folder_button->connect_compat("pressed", this, "_on_folder_button_pressed");
 		hbc->add_child(folder_button);
 
 		_folder_dialog = memnew(FileDialog);
 		_folder_dialog->set_mode(FileDialog::MODE_OPEN_DIR);
-		_folder_dialog->connect("dir_selected", this, "_on_folder_selected");
+		_folder_dialog->connect_compat("dir_selected", this, "_on_folder_selected");
 		add_child(_folder_dialog);
 
 		gc->add_child(hbc);
@@ -563,8 +563,8 @@ const char *FindInFilesPanel::SIGNAL_FILES_MODIFIED = "files_modified";
 FindInFilesPanel::FindInFilesPanel() {
 
 	_finder = memnew(FindInFiles);
-	_finder->connect(FindInFiles::SIGNAL_RESULT_FOUND, this, "_on_result_found");
-	_finder->connect(FindInFiles::SIGNAL_FINISHED, this, "_on_finished");
+	_finder->connect_compat(FindInFiles::SIGNAL_RESULT_FOUND, this, "_on_result_found");
+	_finder->connect_compat(FindInFiles::SIGNAL_FINISHED, this, "_on_finished");
 	add_child(_finder);
 
 	VBoxContainer *vbc = memnew(VBoxContainer);
@@ -596,7 +596,7 @@ FindInFilesPanel::FindInFilesPanel() {
 
 		_cancel_button = memnew(Button);
 		_cancel_button->set_text(TTR("Cancel"));
-		_cancel_button->connect("pressed", this, "_on_cancel_button_clicked");
+		_cancel_button->connect_compat("pressed", this, "_on_cancel_button_clicked");
 		_cancel_button->hide();
 		hbc->add_child(_cancel_button);
 
@@ -606,8 +606,8 @@ FindInFilesPanel::FindInFilesPanel() {
 	_results_display = memnew(Tree);
 	_results_display->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("source", "EditorFonts"));
 	_results_display->set_v_size_flags(SIZE_EXPAND_FILL);
-	_results_display->connect("item_selected", this, "_on_result_selected");
-	_results_display->connect("item_edited", this, "_on_item_edited");
+	_results_display->connect_compat("item_selected", this, "_on_result_selected");
+	_results_display->connect_compat("item_edited", this, "_on_item_edited");
 	_results_display->set_hide_root(true);
 	_results_display->set_select_mode(Tree::SELECT_ROW);
 	_results_display->set_allow_rmb_select(true);
@@ -625,12 +625,12 @@ FindInFilesPanel::FindInFilesPanel() {
 
 		_replace_line_edit = memnew(LineEdit);
 		_replace_line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
-		_replace_line_edit->connect("text_changed", this, "_on_replace_text_changed");
+		_replace_line_edit->connect_compat("text_changed", this, "_on_replace_text_changed");
 		_replace_container->add_child(_replace_line_edit);
 
 		_replace_all_button = memnew(Button);
 		_replace_all_button->set_text(TTR("Replace all (no undo)"));
-		_replace_all_button->connect("pressed", this, "_on_replace_all_clicked");
+		_replace_all_button->connect_compat("pressed", this, "_on_replace_all_clicked");
 		_replace_container->add_child(_replace_all_button);
 
 		_replace_container->hide();

+ 16 - 16
editor/groups_editor.cpp

@@ -435,9 +435,9 @@ GroupDialog::GroupDialog() {
 	groups->set_allow_rmb_select(true);
 	groups->set_v_size_flags(SIZE_EXPAND_FILL);
 	groups->add_constant_override("draw_guides", 1);
-	groups->connect("item_selected", this, "_group_selected");
-	groups->connect("button_pressed", this, "_delete_group_pressed");
-	groups->connect("item_edited", this, "_group_renamed");
+	groups->connect_compat("item_selected", this, "_group_selected");
+	groups->connect_compat("button_pressed", this, "_delete_group_pressed");
+	groups->connect_compat("item_edited", this, "_group_renamed");
 
 	HBoxContainer *chbc = memnew(HBoxContainer);
 	vbc_left->add_child(chbc);
@@ -446,12 +446,12 @@ GroupDialog::GroupDialog() {
 	add_group_text = memnew(LineEdit);
 	chbc->add_child(add_group_text);
 	add_group_text->set_h_size_flags(SIZE_EXPAND_FILL);
-	add_group_text->connect("text_entered", this, "_add_group_pressed");
+	add_group_text->connect_compat("text_entered", this, "_add_group_pressed");
 
 	Button *add_group_button = memnew(Button);
 	add_group_button->set_text(TTR("Add"));
 	chbc->add_child(add_group_button);
-	add_group_button->connect("pressed", this, "_add_group_pressed", varray(String()));
+	add_group_button->connect_compat("pressed", this, "_add_group_pressed", varray(String()));
 
 	VBoxContainer *vbc_add = memnew(VBoxContainer);
 	hbc->add_child(vbc_add);
@@ -468,7 +468,7 @@ GroupDialog::GroupDialog() {
 	nodes_to_add->set_select_mode(Tree::SELECT_MULTI);
 	nodes_to_add->set_v_size_flags(SIZE_EXPAND_FILL);
 	nodes_to_add->add_constant_override("draw_guides", 1);
-	nodes_to_add->connect("item_selected", this, "_nodes_to_add_selected");
+	nodes_to_add->connect_compat("item_selected", this, "_nodes_to_add_selected");
 
 	HBoxContainer *add_filter_hbc = memnew(HBoxContainer);
 	add_filter_hbc->add_constant_override("separate", 0);
@@ -478,7 +478,7 @@ GroupDialog::GroupDialog() {
 	add_filter->set_h_size_flags(SIZE_EXPAND_FILL);
 	add_filter->set_placeholder(TTR("Filter nodes"));
 	add_filter_hbc->add_child(add_filter);
-	add_filter->connect("text_changed", this, "_add_filter_changed");
+	add_filter->connect_compat("text_changed", this, "_add_filter_changed");
 
 	VBoxContainer *vbc_buttons = memnew(VBoxContainer);
 	hbc->add_child(vbc_buttons);
@@ -487,7 +487,7 @@ GroupDialog::GroupDialog() {
 
 	add_button = memnew(ToolButton);
 	add_button->set_text(TTR("Add"));
-	add_button->connect("pressed", this, "_add_pressed");
+	add_button->connect_compat("pressed", this, "_add_pressed");
 
 	vbc_buttons->add_child(add_button);
 	vbc_buttons->add_spacer();
@@ -496,7 +496,7 @@ GroupDialog::GroupDialog() {
 
 	remove_button = memnew(ToolButton);
 	remove_button->set_text(TTR("Remove"));
-	remove_button->connect("pressed", this, "_removed_pressed");
+	remove_button->connect_compat("pressed", this, "_removed_pressed");
 
 	vbc_buttons->add_child(remove_button);
 
@@ -515,7 +515,7 @@ GroupDialog::GroupDialog() {
 	nodes_to_remove->set_hide_folding(true);
 	nodes_to_remove->set_select_mode(Tree::SELECT_MULTI);
 	nodes_to_remove->add_constant_override("draw_guides", 1);
-	nodes_to_remove->connect("item_selected", this, "_node_to_remove_selected");
+	nodes_to_remove->connect_compat("item_selected", this, "_node_to_remove_selected");
 
 	HBoxContainer *remove_filter_hbc = memnew(HBoxContainer);
 	remove_filter_hbc->add_constant_override("separate", 0);
@@ -525,7 +525,7 @@ GroupDialog::GroupDialog() {
 	remove_filter->set_h_size_flags(SIZE_EXPAND_FILL);
 	remove_filter->set_placeholder(TTR("Filter nodes"));
 	remove_filter_hbc->add_child(remove_filter);
-	remove_filter->connect("text_changed", this, "_remove_filter_changed");
+	remove_filter->connect_compat("text_changed", this, "_remove_filter_changed");
 
 	group_empty = memnew(Label());
 	group_empty->set_text(TTR("Empty groups will be automatically removed."));
@@ -686,12 +686,12 @@ GroupsEditor::GroupsEditor() {
 	group_dialog = memnew(GroupDialog);
 	group_dialog->set_as_toplevel(true);
 	add_child(group_dialog);
-	group_dialog->connect("group_edited", this, "update_tree");
+	group_dialog->connect_compat("group_edited", this, "update_tree");
 
 	Button *group_dialog_button = memnew(Button);
 	group_dialog_button->set_text(TTR("Manage Groups"));
 	vbc->add_child(group_dialog_button);
-	group_dialog_button->connect("pressed", this, "_show_group_dialog");
+	group_dialog_button->connect_compat("pressed", this, "_show_group_dialog");
 
 	HBoxContainer *hbc = memnew(HBoxContainer);
 	vbc->add_child(hbc);
@@ -699,18 +699,18 @@ GroupsEditor::GroupsEditor() {
 	group_name = memnew(LineEdit);
 	group_name->set_h_size_flags(SIZE_EXPAND_FILL);
 	hbc->add_child(group_name);
-	group_name->connect("text_entered", this, "_add_group");
+	group_name->connect_compat("text_entered", this, "_add_group");
 
 	add = memnew(Button);
 	add->set_text(TTR("Add"));
 	hbc->add_child(add);
-	add->connect("pressed", this, "_add_group", varray(String()));
+	add->connect_compat("pressed", this, "_add_group", varray(String()));
 
 	tree = memnew(Tree);
 	tree->set_hide_root(true);
 	tree->set_v_size_flags(SIZE_EXPAND_FILL);
 	vbc->add_child(tree);
-	tree->connect("button_pressed", this, "_remove_group");
+	tree->connect_compat("button_pressed", this, "_remove_group");
 	tree->add_constant_override("draw_guides", 1);
 	add_constant_override("separation", 3 * EDSCALE);
 }

+ 5 - 5
editor/import_dock.cpp

@@ -537,26 +537,26 @@ ImportDock::ImportDock() {
 	add_margin_child(TTR("Import As:"), hb);
 	import_as = memnew(OptionButton);
 	import_as->set_disabled(true);
-	import_as->connect("item_selected", this, "_importer_selected");
+	import_as->connect_compat("item_selected", this, "_importer_selected");
 	hb->add_child(import_as);
 	import_as->set_h_size_flags(SIZE_EXPAND_FILL);
 	preset = memnew(MenuButton);
 	preset->set_text(TTR("Preset"));
 	preset->set_disabled(true);
-	preset->get_popup()->connect("index_pressed", this, "_preset_selected");
+	preset->get_popup()->connect_compat("index_pressed", this, "_preset_selected");
 	hb->add_child(preset);
 
 	import_opts = memnew(EditorInspector);
 	add_child(import_opts);
 	import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
-	import_opts->connect("property_toggled", this, "_property_toggled");
+	import_opts->connect_compat("property_toggled", this, "_property_toggled");
 
 	hb = memnew(HBoxContainer);
 	add_child(hb);
 	import = memnew(Button);
 	import->set_text(TTR("Reimport"));
 	import->set_disabled(true);
-	import->connect("pressed", this, "_reimport_attempt");
+	import->connect_compat("pressed", this, "_reimport_attempt");
 	hb->add_spacer();
 	hb->add_child(import);
 	hb->add_spacer();
@@ -564,7 +564,7 @@ ImportDock::ImportDock() {
 	reimport_confirm = memnew(ConfirmationDialog);
 	reimport_confirm->get_ok()->set_text(TTR("Save scenes, re-import and restart"));
 	add_child(reimport_confirm);
-	reimport_confirm->connect("confirmed", this, "_reimport_and_restart");
+	reimport_confirm->connect_compat("confirmed", this, "_reimport_and_restart");
 
 	VBoxContainer *vbc_confirm = memnew(VBoxContainer());
 	vbc_confirm->add_child(memnew(Label(TTR("Changing the type of an imported file requires editor restart."))));

+ 13 - 13
editor/inspector_dock.cpp

@@ -511,14 +511,14 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	resource_new_button->set_tooltip(TTR("Create a new resource in memory and edit it."));
 	resource_new_button->set_icon(get_icon("New", "EditorIcons"));
 	general_options_hb->add_child(resource_new_button);
-	resource_new_button->connect("pressed", this, "_new_resource");
+	resource_new_button->connect_compat("pressed", this, "_new_resource");
 	resource_new_button->set_focus_mode(Control::FOCUS_NONE);
 
 	resource_load_button = memnew(ToolButton);
 	resource_load_button->set_tooltip(TTR("Load an existing resource from disk and edit it."));
 	resource_load_button->set_icon(get_icon("Load", "EditorIcons"));
 	general_options_hb->add_child(resource_load_button);
-	resource_load_button->connect("pressed", this, "_open_resource_selector");
+	resource_load_button->connect_compat("pressed", this, "_open_resource_selector");
 	resource_load_button->set_focus_mode(Control::FOCUS_NONE);
 
 	resource_save_button = memnew(MenuButton);
@@ -527,7 +527,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	general_options_hb->add_child(resource_save_button);
 	resource_save_button->get_popup()->add_item(TTR("Save"), RESOURCE_SAVE);
 	resource_save_button->get_popup()->add_item(TTR("Save As..."), RESOURCE_SAVE_AS);
-	resource_save_button->get_popup()->connect("id_pressed", this, "_menu_option");
+	resource_save_button->get_popup()->connect_compat("id_pressed", this, "_menu_option");
 	resource_save_button->set_focus_mode(Control::FOCUS_NONE);
 	resource_save_button->set_disabled(true);
 
@@ -539,7 +539,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	backward_button->set_flat(true);
 	backward_button->set_tooltip(TTR("Go to the previous edited object in history."));
 	backward_button->set_disabled(true);
-	backward_button->connect("pressed", this, "_edit_back");
+	backward_button->connect_compat("pressed", this, "_edit_back");
 
 	forward_button = memnew(ToolButton);
 	general_options_hb->add_child(forward_button);
@@ -547,14 +547,14 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	forward_button->set_flat(true);
 	forward_button->set_tooltip(TTR("Go to the next edited object in history."));
 	forward_button->set_disabled(true);
-	forward_button->connect("pressed", this, "_edit_forward");
+	forward_button->connect_compat("pressed", this, "_edit_forward");
 
 	history_menu = memnew(MenuButton);
 	history_menu->set_tooltip(TTR("History of recently edited objects."));
 	history_menu->set_icon(get_icon("History", "EditorIcons"));
 	general_options_hb->add_child(history_menu);
-	history_menu->connect("about_to_show", this, "_prepare_history");
-	history_menu->get_popup()->connect("id_pressed", this, "_select_history");
+	history_menu->connect_compat("about_to_show", this, "_prepare_history");
+	history_menu->get_popup()->connect_compat("id_pressed", this, "_select_history");
 
 	HBoxContainer *node_info_hb = memnew(HBoxContainer);
 	add_child(node_info_hb);
@@ -567,12 +567,12 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	object_menu->set_icon(get_icon("Tools", "EditorIcons"));
 	node_info_hb->add_child(object_menu);
 	object_menu->set_tooltip(TTR("Object properties."));
-	object_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+	object_menu->get_popup()->connect_compat("id_pressed", this, "_menu_option");
 
 	new_resource_dialog = memnew(CreateDialog);
 	editor->get_gui_base()->add_child(new_resource_dialog);
 	new_resource_dialog->set_base_type("Resource");
-	new_resource_dialog->connect("create", this, "_resource_created");
+	new_resource_dialog->connect_compat("create", this, "_resource_created");
 
 	search = memnew(LineEdit);
 	search->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -588,7 +588,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	warning->add_color_override("font_color", get_color("warning_color", "Editor"));
 	warning->set_clip_text(true);
 	warning->hide();
-	warning->connect("pressed", this, "_warning_pressed");
+	warning->connect_compat("pressed", this, "_warning_pressed");
 
 	warning_dialog = memnew(AcceptDialog);
 	editor->get_gui_base()->add_child(warning_dialog);
@@ -596,7 +596,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 	load_resource_dialog = memnew(EditorFileDialog);
 	add_child(load_resource_dialog);
 	load_resource_dialog->set_current_dir("res://");
-	load_resource_dialog->connect("file_selected", this, "_resource_file_selected");
+	load_resource_dialog->connect_compat("file_selected", this, "_resource_file_selected");
 
 	inspector = memnew(EditorInspector);
 	add_child(inspector);
@@ -612,8 +612,8 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
 
 	inspector->set_use_filter(true); // TODO: check me
 
-	inspector->connect("resource_selected", this, "_resource_selected");
-	inspector->connect("property_keyed", this, "_property_keyed");
+	inspector->connect_compat("resource_selected", this, "_resource_selected");
+	inspector->connect_compat("property_keyed", this, "_property_keyed");
 }
 
 InspectorDock::~InspectorDock() {

+ 2 - 2
editor/node_dock.cpp

@@ -107,7 +107,7 @@ NodeDock::NodeDock() {
 	connections_button->set_h_size_flags(SIZE_EXPAND_FILL);
 	connections_button->set_clip_text(true);
 	mode_hb->add_child(connections_button);
-	connections_button->connect("pressed", this, "show_connections");
+	connections_button->connect_compat("pressed", this, "show_connections");
 
 	groups_button = memnew(ToolButton);
 	groups_button->set_text(TTR("Groups"));
@@ -116,7 +116,7 @@ NodeDock::NodeDock() {
 	groups_button->set_h_size_flags(SIZE_EXPAND_FILL);
 	groups_button->set_clip_text(true);
 	mode_hb->add_child(groups_button);
-	groups_button->connect("pressed", this, "show_groups");
+	groups_button->connect_compat("pressed", this, "show_groups");
 
 	connections = memnew(ConnectionsDock(EditorNode::get_singleton()));
 	connections->set_undoredo(EditorNode::get_undo_redo());

+ 4 - 4
editor/plugin_config_dialog.cpp

@@ -132,8 +132,8 @@ void PluginConfigDialog::_on_required_text_changed(const String &) {
 void PluginConfigDialog::_notification(int p_what) {
 	switch (p_what) {
 		case NOTIFICATION_READY: {
-			connect("confirmed", this, "_on_confirmed");
-			get_cancel()->connect("pressed", this, "_on_cancelled");
+			connect_compat("confirmed", this, "_on_confirmed");
+			get_cancel()->connect_compat("pressed", this, "_on_cancelled");
 		} break;
 
 		case NOTIFICATION_POST_POPUP: {
@@ -194,7 +194,7 @@ PluginConfigDialog::PluginConfigDialog() {
 	grid->add_child(name_lb);
 
 	name_edit = memnew(LineEdit);
-	name_edit->connect("text_changed", this, "_on_required_text_changed");
+	name_edit->connect_compat("text_changed", this, "_on_required_text_changed");
 	name_edit->set_placeholder("MyPlugin");
 	grid->add_child(name_edit);
 
@@ -253,7 +253,7 @@ PluginConfigDialog::PluginConfigDialog() {
 	grid->add_child(script_lb);
 
 	script_edit = memnew(LineEdit);
-	script_edit->connect("text_changed", this, "_on_required_text_changed");
+	script_edit->connect_compat("text_changed", this, "_on_required_text_changed");
 	script_edit->set_placeholder("\"plugin.gd\" -> res://addons/my_plugin/plugin.gd");
 	grid->add_child(script_edit);
 

+ 5 - 5
editor/plugins/abstract_polygon_2d_editor.cpp

@@ -209,8 +209,8 @@ void AbstractPolygon2DEditor::_notification(int p_what) {
 			button_delete->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons"));
 			button_edit->set_pressed(true);
 
-			get_tree()->connect("node_removed", this, "_node_removed");
-			create_resource->connect("confirmed", this, "_create_resource");
+			get_tree()->connect_compat("node_removed", this, "_node_removed");
+			create_resource->connect_compat("confirmed", this, "_create_resource");
 		} break;
 	}
 }
@@ -820,17 +820,17 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wi
 	add_child(memnew(VSeparator));
 	button_create = memnew(ToolButton);
 	add_child(button_create);
-	button_create->connect("pressed", this, "_menu_option", varray(MODE_CREATE));
+	button_create->connect_compat("pressed", this, "_menu_option", varray(MODE_CREATE));
 	button_create->set_toggle_mode(true);
 
 	button_edit = memnew(ToolButton);
 	add_child(button_edit);
-	button_edit->connect("pressed", this, "_menu_option", varray(MODE_EDIT));
+	button_edit->connect_compat("pressed", this, "_menu_option", varray(MODE_EDIT));
 	button_edit->set_toggle_mode(true);
 
 	button_delete = memnew(ToolButton);
 	add_child(button_delete);
-	button_delete->connect("pressed", this, "_menu_option", varray(MODE_DELETE));
+	button_delete->connect_compat("pressed", this, "_menu_option", varray(MODE_DELETE));
 	button_delete->set_toggle_mode(true);
 
 	create_resource = memnew(ConfirmationDialog);

+ 16 - 16
editor/plugins/animation_blend_space_1d_editor.cpp

@@ -622,28 +622,28 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 	top_hb->add_child(tool_blend);
 	tool_blend->set_pressed(true);
 	tool_blend->set_tooltip(TTR("Set the blending position within the space"));
-	tool_blend->connect("pressed", this, "_tool_switch", varray(3));
+	tool_blend->connect_compat("pressed", this, "_tool_switch", varray(3));
 
 	tool_select = memnew(ToolButton);
 	tool_select->set_toggle_mode(true);
 	tool_select->set_button_group(bg);
 	top_hb->add_child(tool_select);
 	tool_select->set_tooltip(TTR("Select and move points, create points with RMB."));
-	tool_select->connect("pressed", this, "_tool_switch", varray(0));
+	tool_select->connect_compat("pressed", this, "_tool_switch", varray(0));
 
 	tool_create = memnew(ToolButton);
 	tool_create->set_toggle_mode(true);
 	tool_create->set_button_group(bg);
 	top_hb->add_child(tool_create);
 	tool_create->set_tooltip(TTR("Create points."));
-	tool_create->connect("pressed", this, "_tool_switch", varray(1));
+	tool_create->connect_compat("pressed", this, "_tool_switch", varray(1));
 
 	tool_erase_sep = memnew(VSeparator);
 	top_hb->add_child(tool_erase_sep);
 	tool_erase = memnew(ToolButton);
 	top_hb->add_child(tool_erase);
 	tool_erase->set_tooltip(TTR("Erase points."));
-	tool_erase->connect("pressed", this, "_erase_selected");
+	tool_erase->connect_compat("pressed", this, "_erase_selected");
 
 	top_hb->add_child(memnew(VSeparator));
 
@@ -652,7 +652,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 	top_hb->add_child(snap);
 	snap->set_pressed(true);
 	snap->set_tooltip(TTR("Enable snap and show grid."));
-	snap->connect("pressed", this, "_snap_toggled");
+	snap->connect_compat("pressed", this, "_snap_toggled");
 
 	snap_value = memnew(SpinBox);
 	top_hb->add_child(snap_value);
@@ -670,12 +670,12 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 	edit_value->set_min(-1000);
 	edit_value->set_max(1000);
 	edit_value->set_step(0.01);
-	edit_value->connect("value_changed", this, "_edit_point_pos");
+	edit_value->connect_compat("value_changed", this, "_edit_point_pos");
 
 	open_editor = memnew(Button);
 	edit_hb->add_child(open_editor);
 	open_editor->set_text(TTR("Open Editor"));
-	open_editor->connect("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED);
+	open_editor->connect_compat("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED);
 
 	edit_hb->hide();
 	open_editor->hide();
@@ -691,8 +691,8 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 	panel->set_v_size_flags(SIZE_EXPAND_FILL);
 
 	blend_space_draw = memnew(Control);
-	blend_space_draw->connect("gui_input", this, "_blend_space_gui_input");
-	blend_space_draw->connect("draw", this, "_blend_space_draw");
+	blend_space_draw->connect_compat("gui_input", this, "_blend_space_gui_input");
+	blend_space_draw->connect_compat("draw", this, "_blend_space_draw");
 	blend_space_draw->set_focus_mode(FOCUS_ALL);
 
 	panel->add_child(blend_space_draw);
@@ -724,10 +724,10 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 		bottom_hb->add_child(max_value);
 	}
 
-	snap_value->connect("value_changed", this, "_config_changed");
-	min_value->connect("value_changed", this, "_config_changed");
-	max_value->connect("value_changed", this, "_config_changed");
-	label_value->connect("text_changed", this, "_labels_changed");
+	snap_value->connect_compat("value_changed", this, "_config_changed");
+	min_value->connect_compat("value_changed", this, "_config_changed");
+	max_value->connect_compat("value_changed", this, "_config_changed");
+	label_value->connect_compat("text_changed", this, "_labels_changed");
 
 	error_panel = memnew(PanelContainer);
 	add_child(error_panel);
@@ -740,18 +740,18 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
 
 	menu = memnew(PopupMenu);
 	add_child(menu);
-	menu->connect("id_pressed", this, "_add_menu_type");
+	menu->connect_compat("id_pressed", this, "_add_menu_type");
 
 	animations_menu = memnew(PopupMenu);
 	menu->add_child(animations_menu);
 	animations_menu->set_name("animations");
-	animations_menu->connect("index_pressed", this, "_add_animation_type");
+	animations_menu->connect_compat("index_pressed", this, "_add_animation_type");
 
 	open_file = memnew(EditorFileDialog);
 	add_child(open_file);
 	open_file->set_title(TTR("Open Animation Node"));
 	open_file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-	open_file->connect("file_selected", this, "_file_opened");
+	open_file->connect_compat("file_selected", this, "_file_opened");
 	undo_redo = EditorNode::get_undo_redo();
 
 	selected_point = -1;

+ 26 - 26
editor/plugins/animation_blend_space_2d_editor.cpp

@@ -55,12 +55,12 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_changed() {
 void AnimationNodeBlendSpace2DEditor::edit(const Ref<AnimationNode> &p_node) {
 
 	if (blend_space.is_valid()) {
-		blend_space->disconnect("triangles_updated", this, "_blend_space_changed");
+		blend_space->disconnect_compat("triangles_updated", this, "_blend_space_changed");
 	}
 	blend_space = p_node;
 
 	if (!blend_space.is_null()) {
-		blend_space->connect("triangles_updated", this, "_blend_space_changed");
+		blend_space->connect_compat("triangles_updated", this, "_blend_space_changed");
 		_update_space();
 	}
 }
@@ -870,42 +870,42 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 	top_hb->add_child(tool_blend);
 	tool_blend->set_pressed(true);
 	tool_blend->set_tooltip(TTR("Set the blending position within the space"));
-	tool_blend->connect("pressed", this, "_tool_switch", varray(3));
+	tool_blend->connect_compat("pressed", this, "_tool_switch", varray(3));
 
 	tool_select = memnew(ToolButton);
 	tool_select->set_toggle_mode(true);
 	tool_select->set_button_group(bg);
 	top_hb->add_child(tool_select);
 	tool_select->set_tooltip(TTR("Select and move points, create points with RMB."));
-	tool_select->connect("pressed", this, "_tool_switch", varray(0));
+	tool_select->connect_compat("pressed", this, "_tool_switch", varray(0));
 
 	tool_create = memnew(ToolButton);
 	tool_create->set_toggle_mode(true);
 	tool_create->set_button_group(bg);
 	top_hb->add_child(tool_create);
 	tool_create->set_tooltip(TTR("Create points."));
-	tool_create->connect("pressed", this, "_tool_switch", varray(1));
+	tool_create->connect_compat("pressed", this, "_tool_switch", varray(1));
 
 	tool_triangle = memnew(ToolButton);
 	tool_triangle->set_toggle_mode(true);
 	tool_triangle->set_button_group(bg);
 	top_hb->add_child(tool_triangle);
 	tool_triangle->set_tooltip(TTR("Create triangles by connecting points."));
-	tool_triangle->connect("pressed", this, "_tool_switch", varray(2));
+	tool_triangle->connect_compat("pressed", this, "_tool_switch", varray(2));
 
 	tool_erase_sep = memnew(VSeparator);
 	top_hb->add_child(tool_erase_sep);
 	tool_erase = memnew(ToolButton);
 	top_hb->add_child(tool_erase);
 	tool_erase->set_tooltip(TTR("Erase points and triangles."));
-	tool_erase->connect("pressed", this, "_erase_selected");
+	tool_erase->connect_compat("pressed", this, "_erase_selected");
 	tool_erase->set_disabled(true);
 
 	top_hb->add_child(memnew(VSeparator));
 
 	auto_triangles = memnew(ToolButton);
 	top_hb->add_child(auto_triangles);
-	auto_triangles->connect("pressed", this, "_auto_triangles_toggled");
+	auto_triangles->connect_compat("pressed", this, "_auto_triangles_toggled");
 	auto_triangles->set_toggle_mode(true);
 	auto_triangles->set_tooltip(TTR("Generate blend triangles automatically (instead of manually)"));
 
@@ -916,7 +916,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 	top_hb->add_child(snap);
 	snap->set_pressed(true);
 	snap->set_tooltip(TTR("Enable snap and show grid."));
-	snap->connect("pressed", this, "_snap_toggled");
+	snap->connect_compat("pressed", this, "_snap_toggled");
 
 	snap_x = memnew(SpinBox);
 	top_hb->add_child(snap_x);
@@ -937,7 +937,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 	top_hb->add_child(memnew(Label(TTR("Blend:"))));
 	interpolation = memnew(OptionButton);
 	top_hb->add_child(interpolation);
-	interpolation->connect("item_selected", this, "_config_changed");
+	interpolation->connect_compat("item_selected", this, "_config_changed");
 
 	edit_hb = memnew(HBoxContainer);
 	top_hb->add_child(edit_hb);
@@ -948,17 +948,17 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 	edit_x->set_min(-1000);
 	edit_x->set_step(0.01);
 	edit_x->set_max(1000);
-	edit_x->connect("value_changed", this, "_edit_point_pos");
+	edit_x->connect_compat("value_changed", this, "_edit_point_pos");
 	edit_y = memnew(SpinBox);
 	edit_hb->add_child(edit_y);
 	edit_y->set_min(-1000);
 	edit_y->set_step(0.01);
 	edit_y->set_max(1000);
-	edit_y->connect("value_changed", this, "_edit_point_pos");
+	edit_y->connect_compat("value_changed", this, "_edit_point_pos");
 	open_editor = memnew(Button);
 	edit_hb->add_child(open_editor);
 	open_editor->set_text(TTR("Open Editor"));
-	open_editor->connect("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED);
+	open_editor->connect_compat("pressed", this, "_open_editor", varray(), CONNECT_DEFERRED);
 	edit_hb->hide();
 	open_editor->hide();
 
@@ -999,8 +999,8 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 	panel->set_h_size_flags(SIZE_EXPAND_FILL);
 
 	blend_space_draw = memnew(Control);
-	blend_space_draw->connect("gui_input", this, "_blend_space_gui_input");
-	blend_space_draw->connect("draw", this, "_blend_space_draw");
+	blend_space_draw->connect_compat("gui_input", this, "_blend_space_gui_input");
+	blend_space_draw->connect_compat("draw", this, "_blend_space_draw");
 	blend_space_draw->set_focus_mode(FOCUS_ALL);
 
 	panel->add_child(blend_space_draw);
@@ -1029,14 +1029,14 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 		min_x_value->set_step(0.01);
 	}
 
-	snap_x->connect("value_changed", this, "_config_changed");
-	snap_y->connect("value_changed", this, "_config_changed");
-	max_x_value->connect("value_changed", this, "_config_changed");
-	min_x_value->connect("value_changed", this, "_config_changed");
-	max_y_value->connect("value_changed", this, "_config_changed");
-	min_y_value->connect("value_changed", this, "_config_changed");
-	label_x->connect("text_changed", this, "_labels_changed");
-	label_y->connect("text_changed", this, "_labels_changed");
+	snap_x->connect_compat("value_changed", this, "_config_changed");
+	snap_y->connect_compat("value_changed", this, "_config_changed");
+	max_x_value->connect_compat("value_changed", this, "_config_changed");
+	min_x_value->connect_compat("value_changed", this, "_config_changed");
+	max_y_value->connect_compat("value_changed", this, "_config_changed");
+	min_y_value->connect_compat("value_changed", this, "_config_changed");
+	label_x->connect_compat("text_changed", this, "_labels_changed");
+	label_y->connect_compat("text_changed", this, "_labels_changed");
 
 	error_panel = memnew(PanelContainer);
 	add_child(error_panel);
@@ -1050,18 +1050,18 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
 
 	menu = memnew(PopupMenu);
 	add_child(menu);
-	menu->connect("id_pressed", this, "_add_menu_type");
+	menu->connect_compat("id_pressed", this, "_add_menu_type");
 
 	animations_menu = memnew(PopupMenu);
 	menu->add_child(animations_menu);
 	animations_menu->set_name("animations");
-	animations_menu->connect("index_pressed", this, "_add_animation_type");
+	animations_menu->connect_compat("index_pressed", this, "_add_animation_type");
 
 	open_file = memnew(EditorFileDialog);
 	add_child(open_file);
 	open_file->set_title(TTR("Open Animation Node"));
 	open_file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-	open_file->connect("file_selected", this, "_file_opened");
+	open_file->connect_compat("file_selected", this, "_file_opened");
 	undo_redo = EditorNode::get_undo_redo();
 
 	selected_point = -1;

+ 21 - 21
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -146,11 +146,11 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
 			name->set_expand_to_text_length(true);
 			node->add_child(name);
 			node->set_slot(0, false, 0, Color(), true, 0, get_color("font_color", "Label"));
-			name->connect("text_entered", this, "_node_renamed", varray(agnode));
-			name->connect("focus_exited", this, "_node_renamed_focus_out", varray(name, agnode), CONNECT_DEFERRED);
+			name->connect_compat("text_entered", this, "_node_renamed", varray(agnode));
+			name->connect_compat("focus_exited", this, "_node_renamed_focus_out", varray(name, agnode), CONNECT_DEFERRED);
 			base = 1;
 			node->set_show_close_button(true);
-			node->connect("close_request", this, "_delete_request", varray(E->get()), CONNECT_DEFERRED);
+			node->connect_compat("close_request", this, "_delete_request", varray(E->get()), CONNECT_DEFERRED);
 		}
 
 		for (int i = 0; i < agnode->get_input_count(); i++) {
@@ -173,13 +173,13 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
 				prop->set_object_and_property(AnimationTreeEditor::get_singleton()->get_tree(), base_path);
 				prop->update_property();
 				prop->set_name_split_ratio(0);
-				prop->connect("property_changed", this, "_property_changed");
+				prop->connect_compat("property_changed", this, "_property_changed");
 				node->add_child(prop);
 				visible_properties.push_back(prop);
 			}
 		}
 
-		node->connect("dragged", this, "_node_dragged", varray(E->get()));
+		node->connect_compat("dragged", this, "_node_dragged", varray(E->get()));
 
 		if (AnimationTreeEditor::get_singleton()->can_edit(agnode)) {
 			node->add_child(memnew(HSeparator));
@@ -187,7 +187,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
 			open_in_editor->set_text(TTR("Open Editor"));
 			open_in_editor->set_icon(get_icon("Edit", "EditorIcons"));
 			node->add_child(open_in_editor);
-			open_in_editor->connect("pressed", this, "_open_in_editor", varray(E->get()), CONNECT_DEFERRED);
+			open_in_editor->connect_compat("pressed", this, "_open_in_editor", varray(E->get()), CONNECT_DEFERRED);
 			open_in_editor->set_h_size_flags(SIZE_SHRINK_CENTER);
 		}
 
@@ -198,7 +198,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
 			edit_filters->set_text(TTR("Edit Filters"));
 			edit_filters->set_icon(get_icon("AnimationFilter", "EditorIcons"));
 			node->add_child(edit_filters);
-			edit_filters->connect("pressed", this, "_edit_filters", varray(E->get()), CONNECT_DEFERRED);
+			edit_filters->connect_compat("pressed", this, "_edit_filters", varray(E->get()), CONNECT_DEFERRED);
 			edit_filters->set_h_size_flags(SIZE_SHRINK_CENTER);
 		}
 
@@ -238,7 +238,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
 			animations[E->get()] = pb;
 			node->add_child(pb);
 
-			mb->get_popup()->connect("index_pressed", this, "_anim_selected", varray(options, E->get()), CONNECT_DEFERRED);
+			mb->get_popup()->connect_compat("index_pressed", this, "_anim_selected", varray(options, E->get()), CONNECT_DEFERRED);
 		}
 
 		if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
@@ -911,7 +911,7 @@ bool AnimationNodeBlendTreeEditor::can_edit(const Ref<AnimationNode> &p_node) {
 void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
 
 	if (blend_tree.is_valid()) {
-		blend_tree->disconnect("removed_from_graph", this, "_removed_from_graph");
+		blend_tree->disconnect_compat("removed_from_graph", this, "_removed_from_graph");
 	}
 
 	blend_tree = p_node;
@@ -919,7 +919,7 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
 	if (blend_tree.is_null()) {
 		hide();
 	} else {
-		blend_tree->connect("removed_from_graph", this, "_removed_from_graph");
+		blend_tree->connect_compat("removed_from_graph", this, "_removed_from_graph");
 
 		_update_graph();
 	}
@@ -936,12 +936,12 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
 	graph->add_valid_right_disconnect_type(0);
 	graph->add_valid_left_disconnect_type(0);
 	graph->set_v_size_flags(SIZE_EXPAND_FILL);
-	graph->connect("connection_request", this, "_connection_request", varray(), CONNECT_DEFERRED);
-	graph->connect("disconnection_request", this, "_disconnection_request", varray(), CONNECT_DEFERRED);
-	graph->connect("node_selected", this, "_node_selected");
-	graph->connect("scroll_offset_changed", this, "_scroll_changed");
-	graph->connect("delete_nodes_request", this, "_delete_nodes_request");
-	graph->connect("popup_request", this, "_popup_request");
+	graph->connect_compat("connection_request", this, "_connection_request", varray(), CONNECT_DEFERRED);
+	graph->connect_compat("disconnection_request", this, "_disconnection_request", varray(), CONNECT_DEFERRED);
+	graph->connect_compat("node_selected", this, "_node_selected");
+	graph->connect_compat("scroll_offset_changed", this, "_scroll_changed");
+	graph->connect_compat("delete_nodes_request", this, "_delete_nodes_request");
+	graph->connect_compat("popup_request", this, "_popup_request");
 
 	VSeparator *vs = memnew(VSeparator);
 	graph->get_zoom_hbox()->add_child(vs);
@@ -951,8 +951,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
 	graph->get_zoom_hbox()->add_child(add_node);
 	add_node->set_text(TTR("Add Node..."));
 	graph->get_zoom_hbox()->move_child(add_node, 0);
-	add_node->get_popup()->connect("id_pressed", this, "_add_node");
-	add_node->connect("about_to_show", this, "_update_options_menu");
+	add_node->get_popup()->connect_compat("id_pressed", this, "_add_node");
+	add_node->connect_compat("about_to_show", this, "_update_options_menu");
 
 	add_options.push_back(AddOption("Animation", "AnimationNodeAnimation"));
 	add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot"));
@@ -984,19 +984,19 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
 
 	filter_enabled = memnew(CheckBox);
 	filter_enabled->set_text(TTR("Enable Filtering"));
-	filter_enabled->connect("pressed", this, "_filter_toggled");
+	filter_enabled->connect_compat("pressed", this, "_filter_toggled");
 	filter_vbox->add_child(filter_enabled);
 
 	filters = memnew(Tree);
 	filter_vbox->add_child(filters);
 	filters->set_v_size_flags(SIZE_EXPAND_FILL);
 	filters->set_hide_root(true);
-	filters->connect("item_edited", this, "_filter_edited");
+	filters->connect_compat("item_edited", this, "_filter_edited");
 
 	open_file = memnew(EditorFileDialog);
 	add_child(open_file);
 	open_file->set_title(TTR("Open Animation Node"));
 	open_file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-	open_file->connect("file_selected", this, "_file_opened");
+	open_file->connect_compat("file_selected", this, "_file_opened");
 	undo_redo = EditorNode::get_undo_redo();
 }

+ 27 - 27
editor/plugins/animation_player_editor_plugin.cpp

@@ -99,13 +99,13 @@ void AnimationPlayerEditor::_notification(int p_what) {
 		} break;
 		case NOTIFICATION_ENTER_TREE: {
 
-			tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu");
+			tool_anim->get_popup()->connect_compat("id_pressed", this, "_animation_tool_menu");
 
-			onion_skinning->get_popup()->connect("id_pressed", this, "_onion_skinning_menu");
+			onion_skinning->get_popup()->connect_compat("id_pressed", this, "_onion_skinning_menu");
 
-			blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed");
+			blend_editor.next->connect_compat("item_selected", this, "_blend_editor_next_changed");
 
-			get_tree()->connect("node_removed", this, "_node_removed");
+			get_tree()->connect_compat("node_removed", this, "_node_removed");
 
 			add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel"));
 		} break;
@@ -1504,16 +1504,16 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
 void AnimationPlayerEditor::_start_onion_skinning() {
 
 	// FIXME: Using "idle_frame" makes onion layers update one frame behind the current.
-	if (!get_tree()->is_connected("idle_frame", this, "call_deferred")) {
-		get_tree()->connect("idle_frame", this, "call_deferred", varray("_prepare_onion_layers_1"));
+	if (!get_tree()->is_connected_compat("idle_frame", this, "call_deferred")) {
+		get_tree()->connect_compat("idle_frame", this, "call_deferred", varray("_prepare_onion_layers_1"));
 	}
 }
 
 void AnimationPlayerEditor::_stop_onion_skinning() {
 
-	if (get_tree()->is_connected("idle_frame", this, "call_deferred")) {
+	if (get_tree()->is_connected_compat("idle_frame", this, "call_deferred")) {
 
-		get_tree()->disconnect("idle_frame", this, "call_deferred");
+		get_tree()->disconnect_compat("idle_frame", this, "call_deferred");
 
 		_free_onion_layers();
 
@@ -1630,11 +1630,11 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 
 	accept = memnew(AcceptDialog);
 	add_child(accept);
-	accept->connect("confirmed", this, "_menu_confirm_current");
+	accept->connect_compat("confirmed", this, "_menu_confirm_current");
 
 	delete_dialog = memnew(ConfirmationDialog);
 	add_child(delete_dialog);
-	delete_dialog->connect("confirmed", this, "_animation_remove_confirmed");
+	delete_dialog->connect_compat("confirmed", this, "_animation_remove_confirmed");
 
 	tool_anim = memnew(MenuButton);
 	tool_anim->set_flat(false);
@@ -1679,7 +1679,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 	onion_toggle = memnew(ToolButton);
 	onion_toggle->set_toggle_mode(true);
 	onion_toggle->set_tooltip(TTR("Enable Onion Skinning"));
-	onion_toggle->connect("pressed", this, "_onion_skinning_menu", varray(ONION_SKINNING_ENABLE));
+	onion_toggle->connect_compat("pressed", this, "_onion_skinning_menu", varray(ONION_SKINNING_ENABLE));
 	hb->add_child(onion_toggle);
 
 	onion_skinning = memnew(MenuButton);
@@ -1705,7 +1705,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 	pin->set_toggle_mode(true);
 	pin->set_tooltip(TTR("Pin AnimationPlayer"));
 	hb->add_child(pin);
-	pin->connect("pressed", this, "_pin_pressed");
+	pin->connect_compat("pressed", this, "_pin_pressed");
 
 	file = memnew(EditorFileDialog);
 	add_child(file);
@@ -1729,7 +1729,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 	error_dialog->set_title(TTR("Error!"));
 	add_child(error_dialog);
 
-	name_dialog->connect("confirmed", this, "_animation_name_edited");
+	name_dialog->connect_compat("confirmed", this, "_animation_name_edited");
 
 	blend_editor.dialog = memnew(AcceptDialog);
 	add_child(blend_editor.dialog);
@@ -1745,21 +1745,21 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 	blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times"));
 	updating_blends = false;
 
-	blend_editor.tree->connect("item_edited", this, "_blend_edited");
+	blend_editor.tree->connect_compat("item_edited", this, "_blend_edited");
 
-	autoplay->connect("pressed", this, "_autoplay_pressed");
+	autoplay->connect_compat("pressed", this, "_autoplay_pressed");
 	autoplay->set_toggle_mode(true);
-	play->connect("pressed", this, "_play_pressed");
-	play_from->connect("pressed", this, "_play_from_pressed");
-	play_bw->connect("pressed", this, "_play_bw_pressed");
-	play_bw_from->connect("pressed", this, "_play_bw_from_pressed");
-	stop->connect("pressed", this, "_stop_pressed");
+	play->connect_compat("pressed", this, "_play_pressed");
+	play_from->connect_compat("pressed", this, "_play_from_pressed");
+	play_bw->connect_compat("pressed", this, "_play_bw_pressed");
+	play_bw_from->connect_compat("pressed", this, "_play_bw_from_pressed");
+	stop->connect_compat("pressed", this, "_stop_pressed");
 
-	animation->connect("item_selected", this, "_animation_selected", Vector<Variant>(), true);
+	animation->connect_compat("item_selected", this, "_animation_selected", Vector<Variant>(), true);
 
-	file->connect("file_selected", this, "_dialog_action");
-	frame->connect("value_changed", this, "_seek_value_changed", Vector<Variant>(), true);
-	scale->connect("text_entered", this, "_scale_changed", Vector<Variant>(), true);
+	file->connect_compat("file_selected", this, "_dialog_action");
+	frame->connect_compat("value_changed", this, "_seek_value_changed", Vector<Variant>(), true);
+	scale->connect_compat("text_entered", this, "_scale_changed", Vector<Variant>(), true);
 
 	renaming = false;
 	last_active = false;
@@ -1769,14 +1769,14 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 
 	add_child(track_editor);
 	track_editor->set_v_size_flags(SIZE_EXPAND_FILL);
-	track_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
-	track_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
+	track_editor->connect_compat("timeline_changed", this, "_animation_key_editor_seek");
+	track_editor->connect_compat("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
 
 	_update_player();
 
 	// Onion skinning.
 
-	track_editor->connect("visibility_changed", this, "_editor_visibility_changed");
+	track_editor->connect_compat("visibility_changed", this, "_editor_visibility_changed");
 
 	onion.enabled = false;
 	onion.past = true;

+ 16 - 16
editor/plugins/animation_state_machine_editor.cpp

@@ -1276,21 +1276,21 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
 	tool_select->set_button_group(bg);
 	tool_select->set_pressed(true);
 	tool_select->set_tooltip(TTR("Select and move nodes.\nRMB to add new nodes.\nShift+LMB to create connections."));
-	tool_select->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
+	tool_select->connect_compat("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
 
 	tool_create = memnew(ToolButton);
 	top_hb->add_child(tool_create);
 	tool_create->set_toggle_mode(true);
 	tool_create->set_button_group(bg);
 	tool_create->set_tooltip(TTR("Create new nodes."));
-	tool_create->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
+	tool_create->connect_compat("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
 
 	tool_connect = memnew(ToolButton);
 	top_hb->add_child(tool_connect);
 	tool_connect->set_toggle_mode(true);
 	tool_connect->set_button_group(bg);
 	tool_connect->set_tooltip(TTR("Connect nodes."));
-	tool_connect->connect("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
+	tool_connect->connect_compat("pressed", this, "_update_mode", varray(), CONNECT_DEFERRED);
 
 	tool_erase_hb = memnew(HBoxContainer);
 	top_hb->add_child(tool_erase_hb);
@@ -1298,7 +1298,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
 	tool_erase = memnew(ToolButton);
 	tool_erase->set_tooltip(TTR("Remove selected node or transition."));
 	tool_erase_hb->add_child(tool_erase);
-	tool_erase->connect("pressed", this, "_erase_selected");
+	tool_erase->connect_compat("pressed", this, "_erase_selected");
 	tool_erase->set_disabled(true);
 
 	tool_erase_hb->add_child(memnew(VSeparator));
@@ -1306,13 +1306,13 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
 	tool_autoplay = memnew(ToolButton);
 	tool_autoplay->set_tooltip(TTR("Toggle autoplay this animation on start, restart or seek to zero."));
 	tool_erase_hb->add_child(tool_autoplay);
-	tool_autoplay->connect("pressed", this, "_autoplay_selected");
+	tool_autoplay->connect_compat("pressed", this, "_autoplay_selected");
 	tool_autoplay->set_disabled(true);
 
 	tool_end = memnew(ToolButton);
 	tool_end->set_tooltip(TTR("Set the end animation. This is useful for sub-transitions."));
 	tool_erase_hb->add_child(tool_end);
-	tool_end->connect("pressed", this, "_end_selected");
+	tool_end->connect_compat("pressed", this, "_end_selected");
 	tool_end->set_disabled(true);
 
 	top_hb->add_child(memnew(VSeparator));
@@ -1333,26 +1333,26 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
 
 	state_machine_draw = memnew(Control);
 	panel->add_child(state_machine_draw);
-	state_machine_draw->connect("gui_input", this, "_state_machine_gui_input");
-	state_machine_draw->connect("draw", this, "_state_machine_draw");
+	state_machine_draw->connect_compat("gui_input", this, "_state_machine_gui_input");
+	state_machine_draw->connect_compat("draw", this, "_state_machine_draw");
 	state_machine_draw->set_focus_mode(FOCUS_ALL);
 
 	state_machine_play_pos = memnew(Control);
 	state_machine_draw->add_child(state_machine_play_pos);
 	state_machine_play_pos->set_mouse_filter(MOUSE_FILTER_PASS); //pass all to parent
 	state_machine_play_pos->set_anchors_and_margins_preset(PRESET_WIDE);
-	state_machine_play_pos->connect("draw", this, "_state_machine_pos_draw");
+	state_machine_play_pos->connect_compat("draw", this, "_state_machine_pos_draw");
 
 	v_scroll = memnew(VScrollBar);
 	state_machine_draw->add_child(v_scroll);
 	v_scroll->set_anchors_and_margins_preset(PRESET_RIGHT_WIDE);
-	v_scroll->connect("value_changed", this, "_scroll_changed");
+	v_scroll->connect_compat("value_changed", this, "_scroll_changed");
 
 	h_scroll = memnew(HScrollBar);
 	state_machine_draw->add_child(h_scroll);
 	h_scroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE);
 	h_scroll->set_margin(MARGIN_RIGHT, -v_scroll->get_size().x * EDSCALE);
-	h_scroll->connect("value_changed", this, "_scroll_changed");
+	h_scroll->connect_compat("value_changed", this, "_scroll_changed");
 
 	error_panel = memnew(PanelContainer);
 	add_child(error_panel);
@@ -1366,25 +1366,25 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
 
 	menu = memnew(PopupMenu);
 	add_child(menu);
-	menu->connect("id_pressed", this, "_add_menu_type");
+	menu->connect_compat("id_pressed", this, "_add_menu_type");
 
 	animations_menu = memnew(PopupMenu);
 	menu->add_child(animations_menu);
 	animations_menu->set_name("animations");
-	animations_menu->connect("index_pressed", this, "_add_animation_type");
+	animations_menu->connect_compat("index_pressed", this, "_add_animation_type");
 
 	name_edit = memnew(LineEdit);
 	state_machine_draw->add_child(name_edit);
 	name_edit->hide();
-	name_edit->connect("text_entered", this, "_name_edited");
-	name_edit->connect("focus_exited", this, "_name_edited_focus_out");
+	name_edit->connect_compat("text_entered", this, "_name_edited");
+	name_edit->connect_compat("focus_exited", this, "_name_edited_focus_out");
 	name_edit->set_as_toplevel(true);
 
 	open_file = memnew(EditorFileDialog);
 	add_child(open_file);
 	open_file->set_title(TTR("Open Animation Node"));
 	open_file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
-	open_file->connect("file_selected", this, "_file_opened");
+	open_file->connect_compat("file_selected", this, "_file_opened");
 	undo_redo = EditorNode::get_undo_redo();
 
 	over_text = false;

+ 2 - 2
editor/plugins/animation_tree_editor_plugin.cpp

@@ -85,7 +85,7 @@ void AnimationTreeEditor::_update_path() {
 	b->set_button_group(group);
 	b->set_pressed(true);
 	b->set_focus_mode(FOCUS_NONE);
-	b->connect("pressed", this, "_path_button_pressed", varray(-1));
+	b->connect_compat("pressed", this, "_path_button_pressed", varray(-1));
 	path_hb->add_child(b);
 	for (int i = 0; i < button_path.size(); i++) {
 		b = memnew(Button);
@@ -95,7 +95,7 @@ void AnimationTreeEditor::_update_path() {
 		path_hb->add_child(b);
 		b->set_pressed(true);
 		b->set_focus_mode(FOCUS_NONE);
-		b->connect("pressed", this, "_path_button_pressed", varray(i));
+		b->connect_compat("pressed", this, "_path_button_pressed", varray(i));
 	}
 }
 

+ 32 - 32
editor/plugins/asset_library_editor_plugin.cpp

@@ -112,7 +112,7 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
 	icon = memnew(TextureButton);
 	icon->set_custom_minimum_size(Size2(64, 64) * EDSCALE);
 	icon->set_default_cursor_shape(CURSOR_POINTING_HAND);
-	icon->connect("pressed", this, "_asset_clicked");
+	icon->connect_compat("pressed", this, "_asset_clicked");
 
 	hb->add_child(icon);
 
@@ -123,17 +123,17 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
 
 	title = memnew(LinkButton);
 	title->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
-	title->connect("pressed", this, "_asset_clicked");
+	title->connect_compat("pressed", this, "_asset_clicked");
 	vb->add_child(title);
 
 	category = memnew(LinkButton);
 	category->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
-	category->connect("pressed", this, "_category_clicked");
+	category->connect_compat("pressed", this, "_category_clicked");
 	vb->add_child(category);
 
 	author = memnew(LinkButton);
 	author->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
-	author->connect("pressed", this, "_author_clicked");
+	author->connect_compat("pressed", this, "_author_clicked");
 	vb->add_child(author);
 
 	price = memnew(Label);
@@ -263,7 +263,7 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
 	preview.button->set_flat(true);
 	preview.button->set_icon(get_icon("ThumbnailWait", "EditorIcons"));
 	preview.button->set_toggle_mode(true);
-	preview.button->connect("pressed", this, "_preview_click", varray(p_id));
+	preview.button->connect_compat("pressed", this, "_preview_click", varray(p_id));
 	preview_hb->add_child(preview.button);
 	if (!p_video) {
 		preview.image = get_icon("ThumbnailWait", "EditorIcons");
@@ -290,7 +290,7 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
 	description = memnew(RichTextLabel);
 	desc_vbox->add_child(description);
 	description->set_v_size_flags(SIZE_EXPAND_FILL);
-	description->connect("meta_clicked", this, "_link_click");
+	description->connect_compat("meta_clicked", this, "_link_click");
 	description->add_constant_override("line_separation", Math::round(5 * EDSCALE));
 
 	VBoxContainer *previews_vbox = memnew(VBoxContainer);
@@ -526,7 +526,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
 	title->set_h_size_flags(SIZE_EXPAND_FILL);
 
 	dismiss = memnew(TextureButton);
-	dismiss->connect("pressed", this, "_close");
+	dismiss->connect_compat("pressed", this, "_close");
 	title_hb->add_child(dismiss);
 
 	title->set_clip_text(true);
@@ -546,11 +546,11 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
 	install = memnew(Button);
 	install->set_text(TTR("Install..."));
 	install->set_disabled(true);
-	install->connect("pressed", this, "_install");
+	install->connect_compat("pressed", this, "_install");
 
 	retry = memnew(Button);
 	retry->set_text(TTR("Retry"));
-	retry->connect("pressed", this, "_make_request");
+	retry->connect_compat("pressed", this, "_make_request");
 
 	hb2->add_child(retry);
 	hb2->add_child(install);
@@ -558,7 +558,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
 
 	download = memnew(HTTPRequest);
 	add_child(download);
-	download->connect("request_completed", this, "_http_download_completed");
+	download->connect_compat("request_completed", this, "_http_download_completed");
 	download->set_use_threads(EDITOR_DEF("asset_library/use_threads", true));
 
 	download_error = memnew(AcceptDialog);
@@ -567,7 +567,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
 
 	asset_installer = memnew(EditorAssetInstaller);
 	add_child(asset_installer);
-	asset_installer->connect("confirmed", this, "_close");
+	asset_installer->connect_compat("confirmed", this, "_close");
 
 	prev_status = -1;
 
@@ -657,7 +657,7 @@ void EditorAssetLibrary::_install_asset() {
 
 	if (templates_only) {
 		download->set_external_install(true);
-		download->connect("install_asset", this, "_install_external_asset");
+		download->connect_compat("install_asset", this, "_install_external_asset");
 	}
 }
 
@@ -892,7 +892,7 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, Imag
 	iq.queue_id = ++last_queue_id;
 	iq.active = false;
 
-	iq.request->connect("request_completed", this, "_image_request_completed", varray(iq.queue_id));
+	iq.request->connect_compat("request_completed", this, "_image_request_completed", varray(iq.queue_id));
 
 	image_queue[iq.queue_id] = iq;
 
@@ -991,7 +991,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
 	Button *first = memnew(Button);
 	first->set_text(TTR("First"));
 	if (p_page != 0) {
-		first->connect("pressed", this, "_search", varray(0));
+		first->connect_compat("pressed", this, "_search", varray(0));
 	} else {
 		first->set_disabled(true);
 		first->set_focus_mode(Control::FOCUS_NONE);
@@ -1001,7 +1001,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
 	Button *prev = memnew(Button);
 	prev->set_text(TTR("Previous"));
 	if (p_page > 0) {
-		prev->connect("pressed", this, "_search", varray(p_page - 1));
+		prev->connect_compat("pressed", this, "_search", varray(p_page - 1));
 	} else {
 		prev->set_disabled(true);
 		prev->set_focus_mode(Control::FOCUS_NONE);
@@ -1023,7 +1023,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
 
 			Button *current = memnew(Button);
 			current->set_text(itos(i + 1));
-			current->connect("pressed", this, "_search", varray(i));
+			current->connect_compat("pressed", this, "_search", varray(i));
 
 			hbc->add_child(current);
 		}
@@ -1032,7 +1032,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
 	Button *next = memnew(Button);
 	next->set_text(TTR("Next"));
 	if (p_page < p_page_count - 1) {
-		next->connect("pressed", this, "_search", varray(p_page + 1));
+		next->connect_compat("pressed", this, "_search", varray(p_page + 1));
 	} else {
 		next->set_disabled(true);
 		next->set_focus_mode(Control::FOCUS_NONE);
@@ -1043,7 +1043,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
 	Button *last = memnew(Button);
 	last->set_text(TTR("Last"));
 	if (p_page != p_page_count - 1) {
-		last->connect("pressed", this, "_search", varray(p_page_count - 1));
+		last->connect_compat("pressed", this, "_search", varray(p_page_count - 1));
 	} else {
 		last->set_disabled(true);
 		last->set_focus_mode(Control::FOCUS_NONE);
@@ -1229,9 +1229,9 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
 				EditorAssetLibraryItem *item = memnew(EditorAssetLibraryItem);
 				asset_items->add_child(item);
 				item->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"]);
-				item->connect("asset_selected", this, "_select_asset");
-				item->connect("author_selected", this, "_select_author");
-				item->connect("category_selected", this, "_select_category");
+				item->connect_compat("asset_selected", this, "_select_asset");
+				item->connect_compat("author_selected", this, "_select_author");
+				item->connect_compat("category_selected", this, "_select_category");
 
 				if (r.has("icon_url") && r["icon_url"] != "") {
 					_request_image(item->get_instance_id(), r["icon_url"], IMAGE_QUEUE_ICON, 0);
@@ -1262,7 +1262,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
 			description = memnew(EditorAssetLibraryItemDescription);
 			add_child(description);
 			description->popup_centered_minsize();
-			description->connect("confirmed", this, "_install_asset");
+			description->connect_compat("confirmed", this, "_install_asset");
 
 			description->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"], r["version"], r["version_string"], r["description"], r["download_url"], r["browse_url"], r["download_hash"]);
 
@@ -1374,9 +1374,9 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	filter = memnew(LineEdit);
 	search_hb->add_child(filter);
 	filter->set_h_size_flags(SIZE_EXPAND_FILL);
-	filter->connect("text_entered", this, "_search_text_entered");
+	filter->connect_compat("text_entered", this, "_search_text_entered");
 	search = memnew(Button(TTR("Search")));
-	search->connect("pressed", this, "_search");
+	search->connect_compat("pressed", this, "_search");
 	search_hb->add_child(search);
 
 	if (!p_templates_only)
@@ -1385,12 +1385,12 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	Button *open_asset = memnew(Button);
 	open_asset->set_text(TTR("Import..."));
 	search_hb->add_child(open_asset);
-	open_asset->connect("pressed", this, "_asset_open");
+	open_asset->connect_compat("pressed", this, "_asset_open");
 
 	Button *plugins = memnew(Button);
 	plugins->set_text(TTR("Plugins..."));
 	search_hb->add_child(plugins);
-	plugins->connect("pressed", this, "_manage_plugins");
+	plugins->connect_compat("pressed", this, "_manage_plugins");
 
 	if (p_templates_only) {
 		open_asset->hide();
@@ -1409,7 +1409,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	search_hb2->add_child(sort);
 
 	sort->set_h_size_flags(SIZE_EXPAND_FILL);
-	sort->connect("item_selected", this, "_rerun_search");
+	sort->connect_compat("item_selected", this, "_rerun_search");
 
 	search_hb2->add_child(memnew(VSeparator));
 
@@ -1418,7 +1418,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	categories->add_item(TTR("All"));
 	search_hb2->add_child(categories);
 	categories->set_h_size_flags(SIZE_EXPAND_FILL);
-	categories->connect("item_selected", this, "_rerun_search");
+	categories->connect_compat("item_selected", this, "_rerun_search");
 
 	search_hb2->add_child(memnew(VSeparator));
 
@@ -1430,7 +1430,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	repository->add_item("localhost");
 	repository->set_item_metadata(1, "http://127.0.0.1/asset-library/api");
 
-	repository->connect("item_selected", this, "_repository_changed");
+	repository->connect_compat("item_selected", this, "_repository_changed");
 
 	search_hb2->add_child(repository);
 	repository->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -1445,7 +1445,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	support->get_popup()->add_check_item(TTR("Testing"), SUPPORT_TESTING);
 	support->get_popup()->set_item_checked(SUPPORT_OFFICIAL, true);
 	support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, true);
-	support->get_popup()->connect("id_pressed", this, "_support_toggled");
+	support->get_popup()->connect_compat("id_pressed", this, "_support_toggled");
 
 	/////////
 
@@ -1501,7 +1501,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	request = memnew(HTTPRequest);
 	add_child(request);
 	request->set_use_threads(EDITOR_DEF("asset_library/use_threads", true));
-	request->connect("request_completed", this, "_http_request_completed");
+	request->connect_compat("request_completed", this, "_http_request_completed");
 
 	last_queue_id = 0;
 
@@ -1534,7 +1534,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	asset_open->add_filter("*.zip ; " + TTR("Assets ZIP File"));
 	asset_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
 	add_child(asset_open);
-	asset_open->connect("file_selected", this, "_asset_file_selected");
+	asset_open->connect_compat("file_selected", this, "_asset_file_selected");
 
 	asset_installer = NULL;
 }

+ 7 - 7
editor/plugins/audio_stream_editor_plugin.cpp

@@ -39,7 +39,7 @@
 void AudioStreamEditor::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_READY) {
-		AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed");
+		AudioStreamPreviewGenerator::get_singleton()->connect_compat("preview_updated", this, "_preview_changed");
 	}
 
 	if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
@@ -214,7 +214,7 @@ AudioStreamEditor::AudioStreamEditor() {
 	_dragging = false;
 
 	_player = memnew(AudioStreamPlayer);
-	_player->connect("finished", this, "_on_finished");
+	_player->connect_compat("finished", this, "_on_finished");
 	add_child(_player);
 
 	VBoxContainer *vbox = memnew(VBoxContainer);
@@ -223,13 +223,13 @@ AudioStreamEditor::AudioStreamEditor() {
 
 	_preview = memnew(ColorRect);
 	_preview->set_v_size_flags(SIZE_EXPAND_FILL);
-	_preview->connect("draw", this, "_draw_preview");
+	_preview->connect_compat("draw", this, "_draw_preview");
 	vbox->add_child(_preview);
 
 	_indicator = memnew(Control);
 	_indicator->set_anchors_and_margins_preset(PRESET_WIDE);
-	_indicator->connect("draw", this, "_draw_indicator");
-	_indicator->connect("gui_input", this, "_on_input_indicator");
+	_indicator->connect_compat("draw", this, "_draw_indicator");
+	_indicator->connect_compat("gui_input", this, "_on_input_indicator");
 	_preview->add_child(_indicator);
 
 	HBoxContainer *hbox = memnew(HBoxContainer);
@@ -239,12 +239,12 @@ AudioStreamEditor::AudioStreamEditor() {
 	_play_button = memnew(ToolButton);
 	hbox->add_child(_play_button);
 	_play_button->set_focus_mode(Control::FOCUS_NONE);
-	_play_button->connect("pressed", this, "_play");
+	_play_button->connect_compat("pressed", this, "_play");
 
 	_stop_button = memnew(ToolButton);
 	hbox->add_child(_stop_button);
 	_stop_button->set_focus_mode(Control::FOCUS_NONE);
-	_stop_button->connect("pressed", this, "_stop");
+	_stop_button->connect_compat("pressed", this, "_stop");
 
 	_current_label = memnew(Label);
 	_current_label->set_align(Label::ALIGN_RIGHT);

+ 1 - 1
editor/plugins/camera_editor_plugin.cpp

@@ -81,7 +81,7 @@ CameraEditor::CameraEditor() {
 	preview->set_margin(MARGIN_RIGHT, 0);
 	preview->set_margin(MARGIN_TOP, 0);
 	preview->set_margin(MARGIN_BOTTOM, 10);
-	preview->connect("pressed", this, "_pressed");
+	preview->connect_compat("pressed", this, "_pressed");
 }
 
 void CameraEditorPlugin::edit(Object *p_object) {

+ 53 - 53
editor/plugins/canvas_item_editor_plugin.cpp

@@ -3891,10 +3891,10 @@ void CanvasItemEditor::_notification(int p_what) {
 			select_sb->set_default_margin(Margin(i), 4);
 		}
 
-		AnimationPlayerEditor::singleton->get_track_editor()->connect("visibility_changed", this, "_keying_changed");
+		AnimationPlayerEditor::singleton->get_track_editor()->connect_compat("visibility_changed", this, "_keying_changed");
 		_keying_changed();
-		get_tree()->connect("node_added", this, "_tree_changed", varray());
-		get_tree()->connect("node_removed", this, "_tree_changed", varray());
+		get_tree()->connect_compat("node_added", this, "_tree_changed", varray());
+		get_tree()->connect_compat("node_removed", this, "_tree_changed", varray());
 
 	} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
 
@@ -3902,8 +3902,8 @@ void CanvasItemEditor::_notification(int p_what) {
 	}
 
 	if (p_what == NOTIFICATION_EXIT_TREE) {
-		get_tree()->disconnect("node_added", this, "_tree_changed");
-		get_tree()->disconnect("node_removed", this, "_tree_changed");
+		get_tree()->disconnect_compat("node_added", this, "_tree_changed");
+		get_tree()->disconnect_compat("node_removed", this, "_tree_changed");
 	}
 
 	if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
@@ -4181,7 +4181,7 @@ void CanvasItemEditor::_popup_warning_temporarily(Control *p_control, const floa
 	Timer *timer;
 	if (!popup_temporarily_timers.has(p_control)) {
 		timer = memnew(Timer);
-		timer->connect("timeout", this, "_popup_warning_depop", varray(p_control));
+		timer->connect_compat("timeout", this, "_popup_warning_depop", varray(p_control));
 		timer->set_one_shot(true);
 		add_child(timer);
 
@@ -5410,11 +5410,11 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	editor = p_editor;
 	editor_selection = p_editor->get_editor_selection();
 	editor_selection->add_editor_plugin(this);
-	editor_selection->connect("selection_changed", this, "update");
-	editor_selection->connect("selection_changed", this, "_selection_changed");
+	editor_selection->connect_compat("selection_changed", this, "update");
+	editor_selection->connect_compat("selection_changed", this, "_selection_changed");
 
-	editor->call_deferred("connect", make_binds("play_pressed", this, "_update_override_camera_button", true));
-	editor->call_deferred("connect", make_binds("stop_pressed", this, "_update_override_camera_button", false));
+	editor->call_deferred("connect", make_binds("play_pressed", Callable(this, "_update_override_camera_button"), true));
+	editor->call_deferred("connect", make_binds("stop_pressed", Callable(this, "_update_override_camera_button"), false));
 
 	hb = memnew(HBoxContainer);
 	add_child(hb);
@@ -5434,7 +5434,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	viewport_scrollable->set_clip_contents(true);
 	viewport_scrollable->set_v_size_flags(SIZE_EXPAND_FILL);
 	viewport_scrollable->set_h_size_flags(SIZE_EXPAND_FILL);
-	viewport_scrollable->connect("draw", this, "_update_scrollbars");
+	viewport_scrollable->connect_compat("draw", this, "_update_scrollbars");
 
 	ViewportContainer *scene_tree = memnew(ViewportContainer);
 	viewport_scrollable->add_child(scene_tree);
@@ -5456,8 +5456,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	viewport->set_anchors_and_margins_preset(Control::PRESET_WIDE);
 	viewport->set_clip_contents(true);
 	viewport->set_focus_mode(FOCUS_ALL);
-	viewport->connect("draw", this, "_draw_viewport");
-	viewport->connect("gui_input", this, "_gui_input_viewport");
+	viewport->connect_compat("draw", this, "_draw_viewport");
+	viewport->connect_compat("gui_input", this, "_gui_input_viewport");
 
 	info_overlay = memnew(VBoxContainer);
 	info_overlay->set_anchors_and_margins_preset(Control::PRESET_BOTTOM_LEFT);
@@ -5485,25 +5485,25 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 
 	h_scroll = memnew(HScrollBar);
 	viewport->add_child(h_scroll);
-	h_scroll->connect("value_changed", this, "_update_scroll");
+	h_scroll->connect_compat("value_changed", this, "_update_scroll");
 	h_scroll->hide();
 
 	v_scroll = memnew(VScrollBar);
 	viewport->add_child(v_scroll);
-	v_scroll->connect("value_changed", this, "_update_scroll");
+	v_scroll->connect_compat("value_changed", this, "_update_scroll");
 	v_scroll->hide();
 
 	viewport->add_child(controls_vb);
 
 	zoom_minus = memnew(ToolButton);
 	zoom_hb->add_child(zoom_minus);
-	zoom_minus->connect("pressed", this, "_button_zoom_minus");
+	zoom_minus->connect_compat("pressed", this, "_button_zoom_minus");
 	zoom_minus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", TTR("Zoom Out"), KEY_MASK_CMD | KEY_MINUS));
 	zoom_minus->set_focus_mode(FOCUS_NONE);
 
 	zoom_reset = memnew(ToolButton);
 	zoom_hb->add_child(zoom_reset);
-	zoom_reset->connect("pressed", this, "_button_zoom_reset");
+	zoom_reset->connect_compat("pressed", this, "_button_zoom_reset");
 	zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0));
 	zoom_reset->set_focus_mode(FOCUS_NONE);
 	zoom_reset->set_text_align(Button::TextAlign::ALIGN_CENTER);
@@ -5512,7 +5512,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 
 	zoom_plus = memnew(ToolButton);
 	zoom_hb->add_child(zoom_plus);
-	zoom_plus->connect("pressed", this, "_button_zoom_plus");
+	zoom_plus->connect_compat("pressed", this, "_button_zoom_plus");
 	zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom In"), KEY_MASK_CMD | KEY_EQUAL)); // Usually direct access key for PLUS
 	zoom_plus->set_focus_mode(FOCUS_NONE);
 
@@ -5521,7 +5521,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	select_button = memnew(ToolButton);
 	hb->add_child(select_button);
 	select_button->set_toggle_mode(true);
-	select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SELECT));
+	select_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_SELECT));
 	select_button->set_pressed(true);
 	select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q));
 	select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection"));
@@ -5531,21 +5531,21 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	move_button = memnew(ToolButton);
 	hb->add_child(move_button);
 	move_button->set_toggle_mode(true);
-	move_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_MOVE));
+	move_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_MOVE));
 	move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), KEY_W));
 	move_button->set_tooltip(TTR("Move Mode"));
 
 	rotate_button = memnew(ToolButton);
 	hb->add_child(rotate_button);
 	rotate_button->set_toggle_mode(true);
-	rotate_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_ROTATE));
+	rotate_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_ROTATE));
 	rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E));
 	rotate_button->set_tooltip(TTR("Rotate Mode"));
 
 	scale_button = memnew(ToolButton);
 	hb->add_child(scale_button);
 	scale_button->set_toggle_mode(true);
-	scale_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE));
+	scale_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE));
 	scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), KEY_S));
 	scale_button->set_tooltip(TTR("Scale Mode"));
 
@@ -5554,25 +5554,25 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	list_select_button = memnew(ToolButton);
 	hb->add_child(list_select_button);
 	list_select_button->set_toggle_mode(true);
-	list_select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_LIST_SELECT));
+	list_select_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_LIST_SELECT));
 	list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
 
 	pivot_button = memnew(ToolButton);
 	hb->add_child(pivot_button);
 	pivot_button->set_toggle_mode(true);
-	pivot_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_EDIT_PIVOT));
+	pivot_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_EDIT_PIVOT));
 	pivot_button->set_tooltip(TTR("Click to change object's rotation pivot."));
 
 	pan_button = memnew(ToolButton);
 	hb->add_child(pan_button);
 	pan_button->set_toggle_mode(true);
-	pan_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PAN));
+	pan_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_PAN));
 	pan_button->set_tooltip(TTR("Pan Mode"));
 
 	ruler_button = memnew(ToolButton);
 	hb->add_child(ruler_button);
 	ruler_button->set_toggle_mode(true);
-	ruler_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_RULER));
+	ruler_button->connect_compat("pressed", this, "_button_tool_select", make_binds(TOOL_RULER));
 	ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), KEY_R));
 	ruler_button->set_tooltip(TTR("Ruler Mode"));
 
@@ -5581,14 +5581,14 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	smart_snap_button = memnew(ToolButton);
 	hb->add_child(smart_snap_button);
 	smart_snap_button->set_toggle_mode(true);
-	smart_snap_button->connect("toggled", this, "_button_toggle_smart_snap");
+	smart_snap_button->connect_compat("toggled", this, "_button_toggle_smart_snap");
 	smart_snap_button->set_tooltip(TTR("Toggle smart snapping."));
 	smart_snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_smart_snap", TTR("Use Smart Snap"), KEY_MASK_SHIFT | KEY_S));
 
 	grid_snap_button = memnew(ToolButton);
 	hb->add_child(grid_snap_button);
 	grid_snap_button->set_toggle_mode(true);
-	grid_snap_button->connect("toggled", this, "_button_toggle_grid_snap");
+	grid_snap_button->connect_compat("toggled", this, "_button_toggle_grid_snap");
 	grid_snap_button->set_tooltip(TTR("Toggle grid snapping."));
 	grid_snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_grid_snap", TTR("Use Grid Snap"), KEY_MASK_SHIFT | KEY_G));
 
@@ -5599,7 +5599,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	snap_config_menu->set_switch_on_hover(true);
 
 	PopupMenu *p = snap_config_menu->get_popup();
-	p->connect("id_pressed", this, "_popup_callback");
+	p->connect_compat("id_pressed", this, "_popup_callback");
 	p->set_hide_on_checkable_item_selection(false);
 	p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
 	p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_scale_snap", TTR("Use Scale Snap")), SNAP_USE_SCALE);
@@ -5613,7 +5613,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	smartsnap_config_popup = memnew(PopupMenu);
 	p->add_child(smartsnap_config_popup);
 	smartsnap_config_popup->set_name("SmartSnapping");
-	smartsnap_config_popup->connect("id_pressed", this, "_popup_callback");
+	smartsnap_config_popup->connect_compat("id_pressed", this, "_popup_callback");
 	smartsnap_config_popup->set_hide_on_checkable_item_selection(false);
 	smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to Parent")), SNAP_USE_NODE_PARENT);
 	smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to Node Anchor")), SNAP_USE_NODE_ANCHORS);
@@ -5627,22 +5627,22 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	lock_button = memnew(ToolButton);
 	hb->add_child(lock_button);
 
-	lock_button->connect("pressed", this, "_popup_callback", varray(LOCK_SELECTED));
+	lock_button->connect_compat("pressed", this, "_popup_callback", varray(LOCK_SELECTED));
 	lock_button->set_tooltip(TTR("Lock the selected object in place (can't be moved)."));
 
 	unlock_button = memnew(ToolButton);
 	hb->add_child(unlock_button);
-	unlock_button->connect("pressed", this, "_popup_callback", varray(UNLOCK_SELECTED));
+	unlock_button->connect_compat("pressed", this, "_popup_callback", varray(UNLOCK_SELECTED));
 	unlock_button->set_tooltip(TTR("Unlock the selected object (can be moved)."));
 
 	group_button = memnew(ToolButton);
 	hb->add_child(group_button);
-	group_button->connect("pressed", this, "_popup_callback", varray(GROUP_SELECTED));
+	group_button->connect_compat("pressed", this, "_popup_callback", varray(GROUP_SELECTED));
 	group_button->set_tooltip(TTR("Makes sure the object's children are not selectable."));
 
 	ungroup_button = memnew(ToolButton);
 	hb->add_child(ungroup_button);
-	ungroup_button->connect("pressed", this, "_popup_callback", varray(UNGROUP_SELECTED));
+	ungroup_button->connect_compat("pressed", this, "_popup_callback", varray(UNGROUP_SELECTED));
 	ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected."));
 
 	hb->add_child(memnew(VSeparator));
@@ -5661,13 +5661,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	p->add_separator();
 	p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Custom Bone(s) from Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES);
 	p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Custom Bones")), SKELETON_CLEAR_BONES);
-	p->connect("id_pressed", this, "_popup_callback");
+	p->connect_compat("id_pressed", this, "_popup_callback");
 
 	hb->add_child(memnew(VSeparator));
 
 	override_camera_button = memnew(ToolButton);
 	hb->add_child(override_camera_button);
-	override_camera_button->connect("toggled", this, "_button_override_camera");
+	override_camera_button->connect_compat("toggled", this, "_button_override_camera");
 	override_camera_button->set_toggle_mode(true);
 	override_camera_button->set_disabled(true);
 	_update_override_camera_button(false);
@@ -5677,7 +5677,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	view_menu = memnew(MenuButton);
 	view_menu->set_text(TTR("View"));
 	hb->add_child(view_menu);
-	view_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
+	view_menu->get_popup()->connect_compat("id_pressed", this, "_popup_callback");
 	view_menu->set_switch_on_hover(true);
 
 	p = view_menu->get_popup();
@@ -5705,18 +5705,18 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	presets_menu->set_switch_on_hover(true);
 
 	p = presets_menu->get_popup();
-	p->connect("id_pressed", this, "_popup_callback");
+	p->connect_compat("id_pressed", this, "_popup_callback");
 
 	anchors_popup = memnew(PopupMenu);
 	p->add_child(anchors_popup);
 	anchors_popup->set_name("Anchors");
-	anchors_popup->connect("id_pressed", this, "_popup_callback");
+	anchors_popup->connect_compat("id_pressed", this, "_popup_callback");
 
 	anchor_mode_button = memnew(ToolButton);
 	hb->add_child(anchor_mode_button);
 	anchor_mode_button->set_toggle_mode(true);
 	anchor_mode_button->hide();
-	anchor_mode_button->connect("toggled", this, "_button_toggle_anchor_mode");
+	anchor_mode_button->connect_compat("toggled", this, "_button_toggle_anchor_mode");
 
 	animation_hb = memnew(HBoxContainer);
 	hb->add_child(animation_hb);
@@ -5728,7 +5728,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	key_loc_button->set_flat(true);
 	key_loc_button->set_pressed(true);
 	key_loc_button->set_focus_mode(FOCUS_NONE);
-	key_loc_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS));
+	key_loc_button->connect_compat("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS));
 	key_loc_button->set_tooltip(TTR("Translation mask for inserting keys."));
 	animation_hb->add_child(key_loc_button);
 	key_rot_button = memnew(Button);
@@ -5736,20 +5736,20 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	key_rot_button->set_flat(true);
 	key_rot_button->set_pressed(true);
 	key_rot_button->set_focus_mode(FOCUS_NONE);
-	key_rot_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT));
+	key_rot_button->connect_compat("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT));
 	key_rot_button->set_tooltip(TTR("Rotation mask for inserting keys."));
 	animation_hb->add_child(key_rot_button);
 	key_scale_button = memnew(Button);
 	key_scale_button->set_toggle_mode(true);
 	key_scale_button->set_flat(true);
 	key_scale_button->set_focus_mode(FOCUS_NONE);
-	key_scale_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE));
+	key_scale_button->connect_compat("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE));
 	key_scale_button->set_tooltip(TTR("Scale mask for inserting keys."));
 	animation_hb->add_child(key_scale_button);
 	key_insert_button = memnew(Button);
 	key_insert_button->set_flat(true);
 	key_insert_button->set_focus_mode(FOCUS_NONE);
-	key_insert_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_KEY));
+	key_insert_button->connect_compat("pressed", this, "_popup_callback", varray(ANIM_INSERT_KEY));
 	key_insert_button->set_tooltip(TTR("Insert keys (based on mask)."));
 	key_insert_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key", TTR("Insert Key"), KEY_INSERT));
 	animation_hb->add_child(key_insert_button);
@@ -5765,7 +5765,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	animation_menu = memnew(MenuButton);
 	animation_menu->set_tooltip(TTR("Animation Key and Pose Options"));
 	animation_hb->add_child(animation_menu);
-	animation_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
+	animation_menu->get_popup()->connect_compat("id_pressed", this, "_popup_callback");
 	animation_menu->set_switch_on_hover(true);
 
 	p = animation_menu->get_popup();
@@ -5778,7 +5778,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_clear_pose", TTR("Clear Pose"), KEY_MASK_SHIFT | KEY_K), ANIM_CLEAR_POSE);
 
 	snap_dialog = memnew(SnapDialog);
-	snap_dialog->connect("confirmed", this, "_snap_changed");
+	snap_dialog->connect_compat("confirmed", this, "_snap_changed");
 	add_child(snap_dialog);
 
 	select_sb = Ref<StyleBoxTexture>(memnew(StyleBoxTexture));
@@ -5786,8 +5786,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	selection_menu = memnew(PopupMenu);
 	add_child(selection_menu);
 	selection_menu->set_custom_minimum_size(Vector2(100, 0));
-	selection_menu->connect("id_pressed", this, "_selection_result_pressed");
-	selection_menu->connect("popup_hide", this, "_selection_menu_hide");
+	selection_menu->connect_compat("id_pressed", this, "_selection_result_pressed");
+	selection_menu->connect_compat("popup_hide", this, "_selection_menu_hide");
 
 	multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);
 	divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);
@@ -6234,11 +6234,11 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p
 void CanvasItemEditorViewport::_notification(int p_what) {
 	switch (p_what) {
 		case NOTIFICATION_ENTER_TREE: {
-			connect("mouse_exited", this, "_on_mouse_exit");
+			connect_compat("mouse_exited", this, "_on_mouse_exit");
 			label->add_color_override("font_color", get_color("warning_color", "Editor"));
 		} break;
 		case NOTIFICATION_EXIT_TREE: {
-			disconnect("mouse_exited", this, "_on_mouse_exit");
+			disconnect_compat("mouse_exited", this, "_on_mouse_exit");
 		} break;
 
 		default: break;
@@ -6276,8 +6276,8 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
 	selector = memnew(AcceptDialog);
 	editor->get_gui_base()->add_child(selector);
 	selector->set_title(TTR("Change Default Type"));
-	selector->connect("confirmed", this, "_on_change_type_confirmed");
-	selector->connect("popup_hide", this, "_on_change_type_closed");
+	selector->connect_compat("confirmed", this, "_on_change_type_confirmed");
+	selector->connect_compat("popup_hide", this, "_on_change_type_closed");
 
 	VBoxContainer *vbc = memnew(VBoxContainer);
 	selector->add_child(vbc);
@@ -6294,7 +6294,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
 		CheckBox *check = memnew(CheckBox);
 		btn_group->add_child(check);
 		check->set_text(types[i]);
-		check->connect("button_down", this, "_on_select_type", varray(check));
+		check->connect_compat("button_down", this, "_on_select_type", varray(check));
 		check->set_button_group(button_group);
 	}
 

+ 3 - 3
editor/plugins/collision_polygon_editor_plugin.cpp

@@ -47,7 +47,7 @@ void Polygon3DEditor::_notification(int p_what) {
 			button_create->set_icon(get_icon("Edit", "EditorIcons"));
 			button_edit->set_icon(get_icon("MovePoint", "EditorIcons"));
 			button_edit->set_pressed(true);
-			get_tree()->connect("node_removed", this, "_node_removed");
+			get_tree()->connect_compat("node_removed", this, "_node_removed");
 
 		} break;
 		case NOTIFICATION_PROCESS: {
@@ -532,12 +532,12 @@ Polygon3DEditor::Polygon3DEditor(EditorNode *p_editor) {
 	add_child(memnew(VSeparator));
 	button_create = memnew(ToolButton);
 	add_child(button_create);
-	button_create->connect("pressed", this, "_menu_option", varray(MODE_CREATE));
+	button_create->connect_compat("pressed", this, "_menu_option", varray(MODE_CREATE));
 	button_create->set_toggle_mode(true);
 
 	button_edit = memnew(ToolButton);
 	add_child(button_edit);
-	button_edit->connect("pressed", this, "_menu_option", varray(MODE_EDIT));
+	button_edit->connect_compat("pressed", this, "_menu_option", varray(MODE_EDIT));
 	button_edit->set_toggle_mode(true);
 
 	mode = MODE_EDIT;

+ 3 - 3
editor/plugins/cpu_particles_2d_editor_plugin.cpp

@@ -240,9 +240,9 @@ void CPUParticles2DEditorPlugin::_notification(int p_what) {
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
 
-		menu->get_popup()->connect("id_pressed", this, "_menu_callback");
+		menu->get_popup()->connect_compat("id_pressed", this, "_menu_callback");
 		menu->set_icon(menu->get_popup()->get_icon("Particles2D", "EditorIcons"));
-		file->connect("file_selected", this, "_file_selected");
+		file->connect_compat("file_selected", this, "_file_selected");
 	}
 }
 
@@ -305,7 +305,7 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) {
 
 	toolbar->add_child(emission_mask);
 
-	emission_mask->connect("confirmed", this, "_generate_emission_mask");
+	emission_mask->connect_compat("confirmed", this, "_generate_emission_mask");
 }
 
 CPUParticles2DEditorPlugin::~CPUParticles2DEditorPlugin() {

+ 1 - 1
editor/plugins/cpu_particles_editor_plugin.cpp

@@ -116,7 +116,7 @@ CPUParticlesEditor::CPUParticlesEditor() {
 	options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE);
 	options->get_popup()->add_separator();
 	options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART);
-	options->get_popup()->connect("id_pressed", this, "_menu_option");
+	options->get_popup()->connect_compat("id_pressed", this, "_menu_option");
 }
 
 void CPUParticlesEditorPlugin::edit(Object *p_object) {

+ 6 - 6
editor/plugins/curve_editor_plugin.cpp

@@ -49,7 +49,7 @@ CurveEditor::CurveEditor() {
 	set_clip_contents(true);
 
 	_context_menu = memnew(PopupMenu);
-	_context_menu->connect("id_pressed", this, "_on_context_menu_item_selected");
+	_context_menu->connect_compat("id_pressed", this, "_on_context_menu_item_selected");
 	add_child(_context_menu);
 
 	_presets_menu = memnew(PopupMenu);
@@ -60,7 +60,7 @@ CurveEditor::CurveEditor() {
 	_presets_menu->add_item(TTR("Ease In"), PRESET_EASE_IN);
 	_presets_menu->add_item(TTR("Ease Out"), PRESET_EASE_OUT);
 	_presets_menu->add_item(TTR("Smoothstep"), PRESET_SMOOTHSTEP);
-	_presets_menu->connect("id_pressed", this, "_on_preset_item_selected");
+	_presets_menu->connect_compat("id_pressed", this, "_on_preset_item_selected");
 	_context_menu->add_child(_presets_menu);
 }
 
@@ -70,15 +70,15 @@ void CurveEditor::set_curve(Ref<Curve> curve) {
 		return;
 
 	if (_curve_ref.is_valid()) {
-		_curve_ref->disconnect(CoreStringNames::get_singleton()->changed, this, "_curve_changed");
-		_curve_ref->disconnect(Curve::SIGNAL_RANGE_CHANGED, this, "_curve_changed");
+		_curve_ref->disconnect_compat(CoreStringNames::get_singleton()->changed, this, "_curve_changed");
+		_curve_ref->disconnect_compat(Curve::SIGNAL_RANGE_CHANGED, this, "_curve_changed");
 	}
 
 	_curve_ref = curve;
 
 	if (_curve_ref.is_valid()) {
-		_curve_ref->connect(CoreStringNames::get_singleton()->changed, this, "_curve_changed");
-		_curve_ref->connect(Curve::SIGNAL_RANGE_CHANGED, this, "_curve_changed");
+		_curve_ref->connect_compat(CoreStringNames::get_singleton()->changed, this, "_curve_changed");
+		_curve_ref->connect_compat(Curve::SIGNAL_RANGE_CHANGED, this, "_curve_changed");
 	}
 
 	_selected_point = -1;

+ 2 - 2
editor/plugins/gi_probe_editor_plugin.cpp

@@ -147,7 +147,7 @@ GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
 	bake = memnew(ToolButton);
 	bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
 	bake->set_text(TTR("Bake GI Probe"));
-	bake->connect("pressed", this, "_bake");
+	bake->connect_compat("pressed", this, "_bake");
 	bake_hb->add_child(bake);
 	bake_info = memnew(Label);
 	bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL);
@@ -159,7 +159,7 @@ GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
 	probe_file = memnew(EditorFileDialog);
 	probe_file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
 	probe_file->add_filter("*.res");
-	probe_file->connect("file_selected", this, "_giprobe_save_path_and_bake");
+	probe_file->connect_compat("file_selected", this, "_giprobe_save_path_and_bake");
 	get_editor_interface()->get_base_control()->add_child(probe_file);
 	probe_file->set_title(TTR("Select path for GIProbe Data File"));
 

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio