Browse Source

Refactor MethodBind to use variadic templates

Removed make_binders and the old style generated binders.
reduz 4 years ago
parent
commit
ee06a70ea6
77 changed files with 1263 additions and 1098 deletions
  1. 3 19
      core/SCsub
  2. 1 1
      core/array.cpp
  3. 657 0
      core/binder_common.h
  4. 1 287
      core/callable_method_pointer.h
  5. 1 1
      core/class_db.cpp
  6. 1 1
      core/class_db.h
  7. 1 1
      core/debugger/remote_debugger.h
  8. 1 1
      core/global_constants.cpp
  9. 1 1
      core/input/input_map.h
  10. 1 1
      core/io/packet_peer.h
  11. 0 390
      core/make_binders.py
  12. 1 1
      core/message_queue.h
  13. 365 167
      core/method_bind.h
  14. 0 3
      core/object.h
  15. 1 1
      core/project_settings.h
  16. 0 1
      core/reference.h
  17. 0 1
      core/resource.h
  18. 1 8
      core/type_info.h
  19. 4 0
      core/typedefs.h
  20. 1 1
      core/undo_redo.h
  21. 10 145
      core/variant_call.cpp
  22. 1 1
      core/variant_op.cpp
  23. 1 1
      editor/editor_plugin.cpp
  24. 1 1
      editor/editor_plugin.h
  25. 0 2
      editor/editor_resource_preview.cpp
  26. 1 2
      editor/editor_settings.h
  27. 1 1
      editor/editor_vcs_interface.h
  28. 1 1
      editor/fileserver/editor_file_server.h
  29. 4 4
      editor/inspector_dock.cpp
  30. 4 4
      editor/inspector_dock.h
  31. 1 1
      main/performance.h
  32. 1 1
      modules/bullet/collision_object_bullet.h
  33. 1 1
      modules/denoise/lightmap_denoiser.h
  34. 2 1
      modules/gdnavigation/rvo_agent.h
  35. 1 1
      modules/jsonrpc/jsonrpc.h
  36. 0 1
      modules/mono/glue/base_object_glue.cpp
  37. 0 1
      modules/mono/glue/glue_header.h
  38. 1 1
      modules/mono/glue/rid_glue.cpp
  39. 1 1
      modules/mono/mono_gd/gd_mono_internals.h
  40. 1 1
      modules/mono/mono_gd/gd_mono_utils.h
  41. 1 1
      modules/visual_script/visual_script_editor.cpp
  42. 1 1
      platform/iphone/game_center.h
  43. 1 1
      platform/iphone/icloud.h
  44. 1 1
      platform/iphone/in_app_store.h
  45. 1 1
      platform/iphone/ios.h
  46. 1 1
      platform/javascript/api/javascript_eval.h
  47. 2 1
      platform/osx/detect.py
  48. 2 1
      platform/uwp/export/export.cpp
  49. 1 2
      scene/2d/physics_body_2d.cpp
  50. 0 1
      scene/2d/tile_map.cpp
  51. 0 1
      scene/3d/gi_probe.cpp
  52. 1 2
      scene/3d/physics_body_3d.cpp
  53. 1 1
      scene/3d/soft_body_3d.cpp
  54. 0 1
      scene/animation/animation_tree.cpp
  55. 0 2
      scene/animation/tween.cpp
  56. 1 1
      scene/debugger/scene_debugger.h
  57. 0 2
      scene/gui/graph_node.cpp
  58. 0 1
      scene/main/canvas_item.cpp
  59. 0 1
      scene/main/node.h
  60. 0 1
      scene/resources/font.cpp
  61. 0 2
      scene/resources/surface_tool.cpp
  62. 0 1
      scene/resources/texture.cpp
  63. 1 1
      servers/audio_server.h
  64. 1 1
      servers/camera_server.h
  65. 0 1
      servers/display_server.cpp
  66. 1 1
      servers/navigation_server_2d.h
  67. 1 1
      servers/navigation_server_3d.h
  68. 0 1
      servers/physics_server_2d.cpp
  69. 1 1
      servers/physics_server_2d.h
  70. 0 1
      servers/physics_server_3d.cpp
  71. 1 1
      servers/physics_server_3d.h
  72. 1 1
      servers/rendering/rendering_device.cpp
  73. 1 1
      servers/rendering/rendering_device.h
  74. 0 1
      servers/rendering_server.cpp
  75. 1 1
      servers/rendering_server.h
  76. 1 0
      tests/test_main.cpp
  77. 165 0
      tests/test_method_bind.h

+ 3 - 19
core/SCsub

@@ -3,7 +3,6 @@
 Import("env")
 Import("env")
 
 
 import core_builders
 import core_builders
-import make_binders
 
 
 env.core_sources = []
 env.core_sources = []
 
 
@@ -87,11 +86,7 @@ if env["builtin_zlib"]:
 # Minizip library, could be unbundled in theory
 # Minizip library, could be unbundled in theory
 # However, our version has some custom modifications, so it won't compile with the system one
 # However, our version has some custom modifications, so it won't compile with the system one
 thirdparty_minizip_dir = "#thirdparty/minizip/"
 thirdparty_minizip_dir = "#thirdparty/minizip/"
-thirdparty_minizip_sources = [
-    "ioapi.c",
-    "unzip.c",
-    "zip.c",
-]
+thirdparty_minizip_sources = ["ioapi.c", "unzip.c", "zip.c"]
 thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
 thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
 env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
 env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
 
 
@@ -152,27 +147,16 @@ env.CommandNoCache(
     env.Run(core_builders.make_certs_header, "Building ca-certificates header."),
     env.Run(core_builders.make_certs_header, "Building ca-certificates header."),
 )
 )
 
 
-# Make binders
-env.CommandNoCache(
-    ["method_bind.gen.inc", "method_bind_ext.gen.inc", "method_bind_free_func.gen.inc"],
-    "make_binders.py",
-    env.Run(make_binders.run, "Generating method binders."),
-)
-
 # Authors
 # Authors
 env.Depends("#core/authors.gen.h", "../AUTHORS.md")
 env.Depends("#core/authors.gen.h", "../AUTHORS.md")
 env.CommandNoCache(
 env.CommandNoCache(
-    "#core/authors.gen.h",
-    "../AUTHORS.md",
-    env.Run(core_builders.make_authors_header, "Generating authors header."),
+    "#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header, "Generating authors header.")
 )
 )
 
 
 # Donors
 # Donors
 env.Depends("#core/donors.gen.h", "../DONORS.md")
 env.Depends("#core/donors.gen.h", "../DONORS.md")
 env.CommandNoCache(
 env.CommandNoCache(
-    "#core/donors.gen.h",
-    "../DONORS.md",
-    env.Run(core_builders.make_donors_header, "Generating donors header."),
+    "#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header, "Generating donors header.")
 )
 )
 
 
 # License
 # License

+ 1 - 1
core/array.cpp

@@ -31,8 +31,8 @@
 #include "array.h"
 #include "array.h"
 
 
 #include "container_type_validate.h"
 #include "container_type_validate.h"
+#include "core/class_db.h"
 #include "core/hashfuncs.h"
 #include "core/hashfuncs.h"
-#include "core/object.h"
 #include "core/script_language.h"
 #include "core/script_language.h"
 #include "core/variant.h"
 #include "core/variant.h"
 #include "core/vector.h"
 #include "core/vector.h"

+ 657 - 0
core/binder_common.h

@@ -0,0 +1,657 @@
+/*************************************************************************/
+/*  binder_common.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 BINDER_COMMON_H
+#define BINDER_COMMON_H
+
+#include "core/list.h"
+#include "core/method_ptrcall.h"
+#include "core/object.h"
+#include "core/simple_type.h"
+#include "core/type_info.h"
+#include "core/typedefs.h"
+#include "core/variant.h"
+#include "core/variant_internal.h"
+
+#include <stdio.h>
+
+template <class T>
+struct VariantCaster {
+	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
+		return p_variant;
+	}
+};
+
+template <class T>
+struct VariantCaster<T &> {
+	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
+		return p_variant;
+	}
+};
+
+template <class T>
+struct VariantCaster<const T &> {
+	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
+		return p_variant;
+	}
+};
+
+#ifdef PTRCALL_ENABLED
+
+#define VARIANT_ENUM_CAST(m_enum)                                            \
+	MAKE_ENUM_TYPE_INFO(m_enum)                                              \
+	template <>                                                              \
+	struct VariantCaster<m_enum> {                                           \
+		static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) {        \
+			return (m_enum)p_variant.operator int();                         \
+		}                                                                    \
+	};                                                                       \
+	template <>                                                              \
+	struct PtrToArg<m_enum> {                                                \
+		_FORCE_INLINE_ static m_enum convert(const void *p_ptr) {            \
+			return m_enum(*reinterpret_cast<const int *>(p_ptr));            \
+		}                                                                    \
+		_FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
+			*(int *)p_ptr = p_val;                                           \
+		}                                                                    \
+	};
+
+#else
+
+#define VARIANT_ENUM_CAST(m_enum)                                     \
+	MAKE_ENUM_TYPE_INFO(m_enum)                                       \
+	template <>                                                       \
+	struct VariantCaster<m_enum> {                                    \
+		static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
+			return (m_enum)p_variant.operator int();                  \
+		}                                                             \
+	};
+
+#endif
+
+// Object enum casts must go here
+VARIANT_ENUM_CAST(Object::ConnectFlags);
+
+VARIANT_ENUM_CAST(Vector3::Axis);
+
+VARIANT_ENUM_CAST(Error);
+VARIANT_ENUM_CAST(Margin);
+VARIANT_ENUM_CAST(Corner);
+VARIANT_ENUM_CAST(Orientation);
+VARIANT_ENUM_CAST(HAlign);
+VARIANT_ENUM_CAST(VAlign);
+VARIANT_ENUM_CAST(PropertyHint);
+VARIANT_ENUM_CAST(PropertyUsageFlags);
+VARIANT_ENUM_CAST(Variant::Type);
+VARIANT_ENUM_CAST(Variant::Operator);
+
+template <>
+struct VariantCaster<char32_t> {
+	static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
+		return (char32_t)p_variant.operator int();
+	}
+};
+#ifdef PTRCALL_ENABLED
+template <>
+struct PtrToArg<char32_t> {
+	_FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
+		return char32_t(*reinterpret_cast<const int *>(p_ptr));
+	}
+	_FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
+		*(int *)p_ptr = p_val;
+	}
+};
+#endif
+
+template <typename T>
+struct VariantObjectClassChecker {
+	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
+		return true;
+	}
+};
+
+template <>
+struct VariantObjectClassChecker<Node *> {
+	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
+		Object *obj = p_variant;
+		Node *node = p_variant;
+		return node || !obj;
+	}
+};
+
+template <>
+struct VariantObjectClassChecker<Control *> {
+	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
+		Object *obj = p_variant;
+		Control *control = p_variant;
+		return control || !obj;
+	}
+};
+
+#ifdef DEBUG_METHODS_ENABLED
+
+template <class T>
+struct VariantCasterAndValidate {
+	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
+				!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+			r_error.argument = p_arg_idx;
+			r_error.expected = argtype;
+		}
+
+		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+	}
+};
+
+template <class T>
+struct VariantCasterAndValidate<T &> {
+	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
+				!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+			r_error.argument = p_arg_idx;
+			r_error.expected = argtype;
+		}
+
+		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+	}
+};
+
+template <class T>
+struct VariantCasterAndValidate<const T &> {
+	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
+				!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
+			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+			r_error.argument = p_arg_idx;
+			r_error.expected = argtype;
+		}
+
+		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+	}
+};
+
+#endif // DEBUG_METHODS_ENABLED
+
+template <class T, class... P, size_t... Is>
+void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
+	r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+	(p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+	(p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+	(void)(p_args); //avoid warning
+}
+
+template <class T, class... P, size_t... Is>
+void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
+	r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+	(p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+	(p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+	(void)(p_args); //avoid warning
+}
+
+#ifdef PTRCALL_ENABLED
+
+template <class T, class... P, size_t... Is>
+void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
+	(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
+}
+
+template <class T, class... P, size_t... Is>
+void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
+	(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
+	PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
+	PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
+	PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
+}
+
+#endif // PTRCALL_ENABLED
+
+template <class T, class... P, size_t... Is>
+void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
+	(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
+}
+
+template <class T, class... P, size_t... Is>
+void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
+	(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
+	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
+	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
+	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
+}
+
+template <class T, class... P>
+void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+
+	if ((size_t)p_argcount < sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+	call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class... P>
+void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
+#ifdef DEBUG_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+	int32_t dvs = default_values.size();
+#ifdef DEBUG_ENABLED
+	if (missing > dvs) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
+	for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+		if (i < p_argcount) {
+			args[i] = p_args[i];
+		} else {
+			args[i] = &default_values[i - p_argcount + (dvs - missing)];
+		}
+	}
+
+	call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class... P>
+void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+
+	if ((size_t)p_argcount < sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+	call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class... P>
+void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
+#ifdef DEBUG_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+	int32_t dvs = default_values.size();
+#ifdef DEBUG_ENABLED
+	if (missing > dvs) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
+	for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+		if (i < p_argcount) {
+			args[i] = p_args[i];
+		} else {
+			args[i] = &default_values[i - p_argcount + (dvs - missing)];
+		}
+	}
+
+	call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
+#ifdef DEBUG_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+	int32_t dvs = default_values.size();
+#ifdef DEBUG_ENABLED
+	if (missing > dvs) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
+	for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+		if (i < p_argcount) {
+			args[i] = p_args[i];
+		} else {
+			args[i] = &default_values[i - p_argcount + (dvs - missing)];
+		}
+	}
+
+	call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
+#ifdef DEBUG_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+	int32_t dvs = default_values.size();
+#ifdef DEBUG_ENABLED
+	if (missing > dvs) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+
+	const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
+	for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+		if (i < p_argcount) {
+			args[i] = p_args[i];
+		} else {
+			args[i] = &default_values[i - p_argcount + (dvs - missing)];
+		}
+	}
+
+	call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+#ifdef PTRCALL_ENABLED
+
+template <class T, class... P>
+void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
+	call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class... P>
+void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
+	call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
+	call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
+	call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
+	call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+#endif // PTRCALL_ENABLED
+
+template <class T, class... P>
+void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
+	call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
+	call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
+	call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
+	call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
+}
+
+// GCC raises "parameter 'p_args' set but not used" when P = {},
+// it's not clever enough to treat other P values as making this branch valid.
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
+#endif
+
+#ifdef DEBUG_METHODS_ENABLED
+
+template <class Q>
+void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
+	if (p_arg == index) {
+		type = GetTypeInfo<Q>::VARIANT_TYPE;
+	}
+	index++;
+}
+
+template <class... P>
+Variant::Type call_get_argument_type(int p_arg) {
+	Variant::Type type = Variant::NIL;
+	int index = 0;
+	// I think rocket science is simpler than modern C++.
+	using expand_type = int[];
+	expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
+	(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
+	(void)index; // Suppress GCC warning.
+	return type;
+}
+
+template <class Q>
+void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
+	if (p_arg == index) {
+		info = GetTypeInfo<Q>::get_class_info();
+	}
+	index++;
+}
+
+template <class... P>
+void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
+	int index = 0;
+	// I think rocket science is simpler than modern C++.
+	using expand_type = int[];
+	expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... };
+	(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
+	(void)index; // Suppress GCC warning.
+}
+
+template <class Q>
+void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
+	if (p_arg == index) {
+		md = GetTypeInfo<Q>::METADATA;
+	}
+	index++;
+}
+
+template <class... P>
+GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
+	GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
+
+	int index = 0;
+	// I think rocket science is simpler than modern C++.
+	using expand_type = int[];
+	expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... };
+	(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
+	(void)index;
+	return md;
+}
+
+#else
+
+template <class... P>
+Variant::Type call_get_argument_type(int p_arg) {
+	return Variant::NIL;
+}
+
+#endif // DEBUG_METHODS_ENABLED
+
+//////////////////////
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
+	r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+	r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+	r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+}
+
+template <class T, class R, class... P>
+void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+
+	if ((size_t)p_argcount < sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+	call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
+	r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+	r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+	r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+	(void)p_args;
+}
+
+template <class T, class R, class... P>
+void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+	if ((size_t)p_argcount > sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+
+	if ((size_t)p_argcount < sizeof...(P)) {
+		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+		r_error.argument = sizeof...(P);
+		return;
+	}
+#endif
+	call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
+	r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+	r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+	r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+
+	(void)p_args;
+}
+
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+#endif // BINDER_COMMON_H

+ 1 - 287
core/callable_method_pointer.h

@@ -31,12 +31,12 @@
 #ifndef CALLABLE_METHOD_POINTER_H
 #ifndef CALLABLE_METHOD_POINTER_H
 #define CALLABLE_METHOD_POINTER_H
 #define CALLABLE_METHOD_POINTER_H
 
 
+#include "core/binder_common.h"
 #include "core/callable.h"
 #include "core/callable.h"
 #include "core/hashfuncs.h"
 #include "core/hashfuncs.h"
 #include "core/object.h"
 #include "core/object.h"
 #include "core/os/copymem.h"
 #include "core/os/copymem.h"
 #include "core/simple_type.h"
 #include "core/simple_type.h"
-#include "core/variant_internal.h"
 
 
 class CallableCustomMethodPointerBase : public CallableCustom {
 class CallableCustomMethodPointerBase : public CallableCustom {
 	uint32_t *comp_ptr;
 	uint32_t *comp_ptr;
@@ -70,219 +70,6 @@ public:
 	virtual uint32_t hash() const;
 	virtual uint32_t hash() const;
 };
 };
 
 
-#ifdef DEBUG_METHODS_ENABLED
-
-template <class T>
-struct VariantCasterAndValidate {
-	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
-		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
-		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
-			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
-			r_error.argument = p_arg_idx;
-			r_error.expected = argtype;
-		}
-
-		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
-	}
-};
-
-template <class T>
-struct VariantCasterAndValidate<T &> {
-	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
-		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
-		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
-			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
-			r_error.argument = p_arg_idx;
-			r_error.expected = argtype;
-		}
-
-		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
-	}
-};
-
-template <class T>
-struct VariantCasterAndValidate<const T &> {
-	static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
-		Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
-		if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
-			r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
-			r_error.argument = p_arg_idx;
-			r_error.expected = argtype;
-		}
-
-		return VariantCaster<T>::cast(*p_args[p_arg_idx]);
-	}
-};
-
-#endif // DEBUG_METHODS_ENABLED
-
-// GCC raises "parameter 'p_args' set but not used" here, probably using a
-// template version that does not have arguments and thus sees it unused, but
-// obviously the template can be used for functions with and without them, and
-// the optimizer will get rid of it anyway.
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
-#endif
-
-template <class T, class... P, size_t... Is>
-void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
-	r_error.error = Callable::CallError::CALL_OK;
-
-#ifdef DEBUG_METHODS_ENABLED
-	(p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
-#else
-	(p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
-#endif
-}
-
-#ifdef PTRCALL_ENABLED
-
-template <class T, class... P, size_t... Is>
-void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
-	(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
-	PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
-	PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
-	PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
-}
-
-#endif // PTRCALL_ENABLED
-
-template <class T, class... P, size_t... Is>
-void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
-	(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
-	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
-	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
-}
-
-template <class T, class R, class... P, size_t... Is>
-void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
-	VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
-}
-
-template <class T, class... P>
-void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-#ifdef DEBUG_METHODS_ENABLED
-	if ((size_t)p_argcount > sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-
-	if ((size_t)p_argcount < sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-#endif
-	call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
-}
-
-#ifdef PTRCALL_ENABLED
-
-template <class T, class... P>
-void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
-	call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
-	call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
-	call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
-	call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-#endif // PTRCALL_ENABLED
-
-template <class T, class... P>
-void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
-	call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
-	call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
-	call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-template <class T, class R, class... P>
-void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
-	call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
-}
-
-#ifdef DEBUG_METHODS_ENABLED
-
-template <class Q>
-void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
-	if (p_arg == index) {
-		type = GetTypeInfo<Q>::VARIANT_TYPE;
-	}
-	index++;
-}
-
-// GCC's warnings checker really doesn't like variadic voodoo.
-// It sees `index` unused below in some branches, so it raises a warning.
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
-#endif
-
-template <class... P>
-Variant::Type call_get_argument_type(int p_arg) {
-	Variant::Type type = Variant::NIL;
-	int index = 0;
-	// I think rocket science is simpler than modern C++.
-	using expand_type = int[];
-	expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... };
-	(void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning.
-	return type;
-}
-
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-#else
-
-template <class... P>
-Variant::Type call_get_argument_type(int p_arg) {
-	return Variant::NIL;
-}
-
-#endif // DEBUG_METHODS_ENABLED
-
 template <class T, class... P>
 template <class T, class... P>
 class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
 class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
 	struct Data {
 	struct Data {
@@ -338,35 +125,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 
 
 // VERSION WITH RETURN
 // VERSION WITH RETURN
 
 
-template <class T, class R, class... P, size_t... Is>
-void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
-	r_error.error = Callable::CallError::CALL_OK;
-
-#ifdef DEBUG_METHODS_ENABLED
-	r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
-#else
-	r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
-#endif
-}
-
-template <class T, class R, class... P>
-void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
-#ifdef DEBUG_METHODS_ENABLED
-	if ((size_t)p_argcount > sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-
-	if ((size_t)p_argcount < sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-#endif
-	call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
-}
-
 template <class T, class R, class... P>
 template <class T, class R, class... P>
 class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
 class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
 	struct Data {
 	struct Data {
@@ -423,35 +181,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 
 
 // CONST VERSION WITH RETURN
 // CONST VERSION WITH RETURN
 
 
-template <class T, class R, class... P, size_t... Is>
-void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
-	r_error.error = Callable::CallError::CALL_OK;
-
-#ifdef DEBUG_METHODS_ENABLED
-	r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
-#else
-	r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
-#endif
-}
-
-template <class T, class R, class... P>
-void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
-#ifdef DEBUG_METHODS_ENABLED
-	if ((size_t)p_argcount > sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-
-	if ((size_t)p_argcount < sizeof...(P)) {
-		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-		r_error.argument = sizeof...(P);
-		return;
-	}
-#endif
-	call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
-}
-
 template <class T, class R, class... P>
 template <class T, class R, class... P>
 class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
 class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
 	struct Data {
 	struct Data {
@@ -512,19 +241,4 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 #define callable_mp(I, M) create_custom_callable_function_pointer(I, M)
 #define callable_mp(I, M) create_custom_callable_function_pointer(I, M)
 #endif
 #endif
 
 
-template <class T, class R, class... P, size_t... Is>
-void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
-	r_error.error = Callable::CallError::CALL_OK;
-
-#ifdef DEBUG_METHODS_ENABLED
-	r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
-#else
-	r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
-#endif
-}
-
-#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
 #endif // CALLABLE_METHOD_POINTER_H
 #endif // CALLABLE_METHOD_POINTER_H

+ 1 - 1
core/class_db.cpp

@@ -1343,7 +1343,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
 
 
 	defvals.resize(p_defcount);
 	defvals.resize(p_defcount);
 	for (int i = 0; i < p_defcount; i++) {
 	for (int i = 0; i < p_defcount; i++) {
-		defvals.write[i] = *p_defs[p_defcount - i - 1];
+		defvals.write[i] = *p_defs[i];
 	}
 	}
 
 
 	p_bind->set_default_arguments(defvals);
 	p_bind->set_default_arguments(defvals);

+ 1 - 1
core/class_db.h

@@ -36,7 +36,7 @@
 #include "core/print_string.h"
 #include "core/print_string.h"
 
 
 /** To bind more then 6 parameters include this:
 /** To bind more then 6 parameters include this:
- *  #include "core/method_bind_ext.gen.inc"
+ *
  */
  */
 
 
 // Makes callable_mp readily available in all classes connecting signals.
 // Makes callable_mp readily available in all classes connecting signals.

+ 1 - 1
core/debugger/remote_debugger.h

@@ -32,10 +32,10 @@
 #define REMOTE_DEBUGGER_H
 #define REMOTE_DEBUGGER_H
 
 
 #include "core/array.h"
 #include "core/array.h"
+#include "core/class_db.h"
 #include "core/debugger/debugger_marshalls.h"
 #include "core/debugger/debugger_marshalls.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/remote_debugger_peer.h"
 #include "core/debugger/remote_debugger_peer.h"
-#include "core/object.h"
 #include "core/string_name.h"
 #include "core/string_name.h"
 #include "core/ustring.h"
 #include "core/ustring.h"
 
 

+ 1 - 1
core/global_constants.cpp

@@ -30,8 +30,8 @@
 
 
 #include "global_constants.h"
 #include "global_constants.h"
 
 
+#include "core/class_db.h"
 #include "core/input/input_event.h"
 #include "core/input/input_event.h"
-#include "core/object.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/variant.h"
 #include "core/variant.h"
 
 

+ 1 - 1
core/input/input_map.h

@@ -31,8 +31,8 @@
 #ifndef INPUT_MAP_H
 #ifndef INPUT_MAP_H
 #define INPUT_MAP_H
 #define INPUT_MAP_H
 
 
+#include "core/class_db.h"
 #include "core/input/input_event.h"
 #include "core/input/input_event.h"
-#include "core/object.h"
 
 
 class InputMap : public Object {
 class InputMap : public Object {
 	GDCLASS(InputMap, Object);
 	GDCLASS(InputMap, Object);

+ 1 - 1
core/io/packet_peer.h

@@ -31,8 +31,8 @@
 #ifndef PACKET_PEER_H
 #ifndef PACKET_PEER_H
 #define PACKET_PEER_H
 #define PACKET_PEER_H
 
 
+#include "core/class_db.h"
 #include "core/io/stream_peer.h"
 #include "core/io/stream_peer.h"
-#include "core/object.h"
 #include "core/ring_buffer.h"
 #include "core/ring_buffer.h"
 
 
 class PacketPeer : public Reference {
 class PacketPeer : public Reference {

+ 0 - 390
core/make_binders.py

@@ -1,390 +0,0 @@
-# -*- coding: ibm850 -*-
-
-template_typed = """
-#ifdef TYPED_METHOD_BIND
-template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
-class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
-public:
-
-	$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
-#ifdef DEBUG_METHODS_ENABLED
-	virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
-	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
-		$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
-		$arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
-		$
-		return GodotTypeInfo::METADATA_NONE;
-	}
-	Variant::Type _get_argument_type(int p_argument) const {
-		$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
-		$arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
-		$
-		return Variant::NIL;
-	}
-	virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
-		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
-		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
-		$
-		return PropertyInfo();
-	}
-#endif
-	virtual String get_instance_class() const {
-		return T::get_class_static();
-	}
-
-	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=Callable::CallError::CALL_OK;
-#ifdef DEBUG_METHODS_ENABLED
-
-		ERR_FAIL_COND_V(!instance,Variant());
-		if (p_arg_count>get_argument_count()) {
-			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=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-			r_error.argument=get_argument_count()-get_default_argument_count();
-			return Variant();
-		}
-		$arg CHECK_ARG(@);
-		$
-#endif
-		$ifret Variant ret = $(instance->*method)($arg, _VC(@)$);
-		$ifret return Variant(ret);$
-		$ifnoret return Variant();$
-	}
-
-#ifdef PTRCALL_ENABLED
-	virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) {
-
-		T *instance=Object::cast_to<T>(p_object);
-		$ifret PtrToArg<R>::encode( $ (instance->*method)($arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret)$ ;
-	}
-#endif
-	MethodBind$argc$$ifret R$$ifconst C$ () {
-#ifdef DEBUG_METHODS_ENABLED
-		_set_const($ifconst true$$ifnoconst false$);
-		_generate_argument_types($argc$);
-#else
-		set_argument_count($argc$);
-#endif
-
-		$ifret _set_returns(true); $
-	}
-};
-
-template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
-MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
-
-	MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) );
-	a->method=p_method;
-	return a;
-}
-#endif
-"""
-
-template = """
-#ifndef TYPED_METHOD_BIND
-$iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$
-class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
-
-public:
-
-	StringName type_name;
-	$ifret R$ $ifnoret void$ (__UnexistingClass::*method)($arg, P@$) $ifconst const$;
-
-#ifdef DEBUG_METHODS_ENABLED
-	virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
-	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
-		$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
-		$arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
-		$
-		return GodotTypeInfo::METADATA_NONE;
-	}
-
-	Variant::Type _get_argument_type(int p_argument) const {
-		$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
-		$arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
-		$
-		return Variant::NIL;
-	}
-
-	virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
-		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
-		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
-		$
-		return PropertyInfo();
-	}
-
-#endif
-	virtual String get_instance_class() const {
-		return type_name;
-	}
-
-	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=Callable::CallError::CALL_OK;
-#ifdef DEBUG_METHODS_ENABLED
-
-		ERR_FAIL_COND_V(!instance,Variant());
-		if (p_arg_count>get_argument_count()) {
-			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=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-			r_error.argument=get_argument_count()-get_default_argument_count();
-			return Variant();
-		}
-
-		$arg CHECK_ARG(@);
-		$
-#endif
-		$ifret Variant ret = $(instance->*method)($arg, _VC(@)$);
-		$ifret return Variant(ret);$
-		$ifnoret return Variant();$
-	}
-#ifdef PTRCALL_ENABLED
-	virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) {
-		__UnexistingClass *instance = (__UnexistingClass*)p_object;
-		$ifret PtrToArg<R>::encode( $ (instance->*method)($arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret) $ ;
-	}
-#endif
-	MethodBind$argc$$ifret R$$ifconst C$ () {
-#ifdef DEBUG_METHODS_ENABLED
-		_set_const($ifconst true$$ifnoconst false$);
-		_generate_argument_types($argc$);
-#else
-		set_argument_count($argc$);
-#endif
-		$ifret _set_returns(true); $
-
-
-	}
-};
-
-template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
-MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
-
-	MethodBind$argc$$ifret R$$ifconst C$ $iftempl <$  $ifret R$ $ifretargs ,$ $arg, P@$ $iftempl >$ * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$ $iftempl <$ $ifret R$ $ifretargs ,$ $arg, P@$ $iftempl >$) );
-	union {
-
-		$ifret R$ $ifnoret void$ (T::*sm)($arg, P@$) $ifconst const$;
-		$ifret R$ $ifnoret void$ (__UnexistingClass::*dm)($arg, P@$) $ifconst const$;
-	} u;
-	u.sm=p_method;
-	a->method=u.dm;
-	a->type_name=T::get_class_static();
-	return a;
-}
-#endif
-"""
-
-
-template_typed_free_func = """
-#ifdef TYPED_METHOD_BIND
-template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
-class FunctionBind$argc$$ifret R$$ifconst C$ : public MethodBind {
-public:
-
-	$ifret R$ $ifnoret void$ (*method) ($ifconst const$ T *$ifargs , $$arg, P@$);
-#ifdef DEBUG_METHODS_ENABLED
-	virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
-	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
-		$ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
-		$arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
-		$
-		return GodotTypeInfo::METADATA_NONE;
-	}
-	Variant::Type _get_argument_type(int p_argument) const {
-		$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
-		$arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
-		$
-		return Variant::NIL;
-	}
-	virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
-		$ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
-		$arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
-		$
-		return PropertyInfo();
-	}
-#endif
-	virtual String get_instance_class() const {
-		return T::get_class_static();
-	}
-
-	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=Callable::CallError::CALL_OK;
-#ifdef DEBUG_METHODS_ENABLED
-
-		ERR_FAIL_COND_V(!instance,Variant());
-		if (p_arg_count>get_argument_count()) {
-			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=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-			r_error.argument=get_argument_count()-get_default_argument_count();
-			return Variant();
-		}
-		$arg CHECK_ARG(@);
-		$
-#endif
-		$ifret Variant ret = $(method)(instance$ifargs , $$arg, _VC(@)$);
-		$ifret return Variant(ret);$
-		$ifnoret return Variant();$
-	}
-
-#ifdef PTRCALL_ENABLED
-	virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) {
-
-		T *instance=Object::cast_to<T>(p_object);
-		$ifret PtrToArg<R>::encode( $ (method)(instance$ifargs , $$arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret)$ ;
-	}
-#endif
-	FunctionBind$argc$$ifret R$$ifconst C$ () {
-#ifdef DEBUG_METHODS_ENABLED
-		_set_const($ifconst true$$ifnoconst false$);
-		_generate_argument_types($argc$);
-#else
-		set_argument_count($argc$);
-#endif
-
-		$ifret _set_returns(true); $
-	}
-};
-
-template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
-MethodBind* create_method_bind($ifret R$ $ifnoret void$ (*p_method)($ifconst const$ T *$ifargs , $$arg, P@$) ) {
-
-	FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) );
-	a->method=p_method;
-	return a;
-}
-#endif
-"""
-
-
-def make_version(template, nargs, argmax, const, ret):
-
-    intext = template
-    from_pos = 0
-    outtext = ""
-
-    while True:
-        to_pos = intext.find("$", from_pos)
-        if to_pos == -1:
-            outtext += intext[from_pos:]
-            break
-        else:
-            outtext += intext[from_pos:to_pos]
-        end = intext.find("$", to_pos + 1)
-        if end == -1:
-            break  # ignore
-        macro = intext[to_pos + 1 : end]
-        cmd = ""
-        data = ""
-
-        if macro.find(" ") != -1:
-            cmd = macro[0 : macro.find(" ")]
-            data = macro[macro.find(" ") + 1 :]
-        else:
-            cmd = macro
-
-        if cmd == "argc":
-            outtext += str(nargs)
-        if cmd == "ifret" and ret:
-            outtext += data
-        if cmd == "ifargs" and nargs:
-            outtext += data
-        if cmd == "ifretargs" and nargs and ret:
-            outtext += data
-        if cmd == "ifconst" and const:
-            outtext += data
-        elif cmd == "ifnoconst" and not const:
-            outtext += data
-        elif cmd == "ifnoret" and not ret:
-            outtext += data
-        elif cmd == "iftempl" and (nargs > 0 or ret):
-            outtext += data
-        elif cmd == "arg,":
-            for i in range(1, nargs + 1):
-                if i > 1:
-                    outtext += ", "
-                outtext += data.replace("@", str(i))
-        elif cmd == "arg":
-            for i in range(1, nargs + 1):
-                outtext += data.replace("@", str(i))
-        elif cmd == "noarg":
-            for i in range(nargs + 1, argmax + 1):
-                outtext += data.replace("@", str(i))
-
-        from_pos = end + 1
-
-    return outtext
-
-
-def run(target, source, env):
-
-    versions = 15
-    versions_ext = 6
-    text = ""
-    text_ext = ""
-    text_free_func = "#ifndef METHOD_BIND_FREE_FUNC_H\n#define METHOD_BIND_FREE_FUNC_H\n"
-    text_free_func += "\n//including this header file allows method binding to use free functions\n"
-    text_free_func += (
-        "//note that the free function must have a pointer to an instance of the class as its first parameter\n"
-    )
-
-    for i in range(0, versions + 1):
-
-        t = ""
-        t += make_version(template, i, versions, False, False)
-        t += make_version(template_typed, i, versions, False, False)
-        t += make_version(template, i, versions, False, True)
-        t += make_version(template_typed, i, versions, False, True)
-        t += make_version(template, i, versions, True, False)
-        t += make_version(template_typed, i, versions, True, False)
-        t += make_version(template, i, versions, True, True)
-        t += make_version(template_typed, i, versions, True, True)
-        if i >= versions_ext:
-            text_ext += t
-        else:
-            text += t
-
-        text_free_func += make_version(template_typed_free_func, i, versions, False, False)
-        text_free_func += make_version(template_typed_free_func, i, versions, False, True)
-        text_free_func += make_version(template_typed_free_func, i, versions, True, False)
-        text_free_func += make_version(template_typed_free_func, i, versions, True, True)
-
-    text_free_func += "#endif"
-
-    with open(target[0], "w") as f:
-        f.write(text)
-
-    with open(target[1], "w") as f:
-        f.write(text_ext)
-
-    with open(target[2], "w") as f:
-        f.write(text_free_func)
-
-
-if __name__ == "__main__":
-    from platform_methods import subprocess_main
-
-    subprocess_main(globals())

+ 1 - 1
core/message_queue.h

@@ -31,7 +31,7 @@
 #ifndef MESSAGE_QUEUE_H
 #ifndef MESSAGE_QUEUE_H
 #define MESSAGE_QUEUE_H
 #define MESSAGE_QUEUE_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/os/thread_safe.h"
 #include "core/os/thread_safe.h"
 
 
 class MessageQueue {
 class MessageQueue {

+ 365 - 167
core/method_bind.h

@@ -31,18 +31,7 @@
 #ifndef METHOD_BIND_H
 #ifndef METHOD_BIND_H
 #define METHOD_BIND_H
 #define METHOD_BIND_H
 
 
-#ifdef DEBUG_ENABLED
-#define DEBUG_METHODS_ENABLED
-#endif
-
-#include "core/list.h"
-#include "core/method_ptrcall.h"
-#include "core/object.h"
-#include "core/type_info.h"
-#include "core/typedefs.h"
-#include "core/variant.h"
-
-#include <stdio.h>
+#include "core/binder_common.h"
 
 
 enum MethodFlags {
 enum MethodFlags {
 
 
@@ -57,151 +46,15 @@ enum MethodFlags {
 	METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
 	METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
 };
 };
 
 
-template <class T>
-struct VariantCaster {
-	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
-	}
-};
-
-template <class T>
-struct VariantCaster<T &> {
-	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
-	}
-};
-
-template <class T>
-struct VariantCaster<const T &> {
-	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
-	}
-};
-
-#define _VC(m_idx) \
-	(VariantCaster<P##m_idx>::cast((m_idx - 1) >= p_arg_count ? get_default_argument(m_idx - 1) : *p_args[m_idx - 1]))
-
-#ifdef PTRCALL_ENABLED
-
-#define VARIANT_ENUM_CAST(m_enum)                                            \
-	MAKE_ENUM_TYPE_INFO(m_enum)                                              \
-	template <>                                                              \
-	struct VariantCaster<m_enum> {                                           \
-		static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) {        \
-			return (m_enum)p_variant.operator int();                         \
-		}                                                                    \
-	};                                                                       \
-	template <>                                                              \
-	struct PtrToArg<m_enum> {                                                \
-		_FORCE_INLINE_ static m_enum convert(const void *p_ptr) {            \
-			return m_enum(*reinterpret_cast<const int *>(p_ptr));            \
-		}                                                                    \
-		_FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
-			*(int *)p_ptr = p_val;                                           \
-		}                                                                    \
-	};
-
-#else
-
-#define VARIANT_ENUM_CAST(m_enum)                                     \
-	MAKE_ENUM_TYPE_INFO(m_enum)                                       \
-	template <>                                                       \
-	struct VariantCaster<m_enum> {                                    \
-		static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
-			return (m_enum)p_variant.operator int();                  \
-		}                                                             \
-	};
-
-#endif
-
-// Object enum casts must go here
-VARIANT_ENUM_CAST(Object::ConnectFlags);
-
-template <typename T>
-struct VariantObjectClassChecker {
-	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
-		return true;
-	}
-};
-
-template <>
-struct VariantObjectClassChecker<Node *> {
-	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
-		Object *obj = p_variant;
-		Node *node = p_variant;
-		return node || !obj;
-	}
-};
-
-template <>
-struct VariantObjectClassChecker<Control *> {
-	static _FORCE_INLINE_ bool check(const Variant &p_variant) {
-		Object *obj = p_variant;
-		Control *control = p_variant;
-		return control || !obj;
-	}
-};
-
-#define CHECK_ARG(m_arg)                                                            \
-	if ((m_arg - 1) < p_arg_count) {                                                \
-		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 = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;       \
-			r_error.argument = m_arg - 1;                                           \
-			r_error.expected = argtype;                                             \
-			return Variant();                                                       \
-		}                                                                           \
-	}
-
-#define CHECK_NOARG(m_arg)                             \
-	{                                                  \
-		if (p_arg##m_arg.get_type() != Variant::NIL) { \
-			if (r_argerror) {                          \
-				*r_argerror = (m_arg - 1);             \
-			}                                          \
-			return CALL_ERROR_EXTRA_ARGUMENT;          \
-		}                                              \
-	}
+VARIANT_ENUM_CAST(MethodFlags)
 
 
 // some helpers
 // some helpers
 
 
-VARIANT_ENUM_CAST(Vector3::Axis);
-
-VARIANT_ENUM_CAST(Error);
-VARIANT_ENUM_CAST(Margin);
-VARIANT_ENUM_CAST(Corner);
-VARIANT_ENUM_CAST(Orientation);
-VARIANT_ENUM_CAST(HAlign);
-VARIANT_ENUM_CAST(VAlign);
-VARIANT_ENUM_CAST(PropertyHint);
-VARIANT_ENUM_CAST(PropertyUsageFlags);
-VARIANT_ENUM_CAST(MethodFlags);
-VARIANT_ENUM_CAST(Variant::Type);
-VARIANT_ENUM_CAST(Variant::Operator);
-
-template <>
-struct VariantCaster<char32_t> {
-	static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
-		return (char32_t)p_variant.operator int();
-	}
-};
-#ifdef PTRCALL_ENABLED
-template <>
-struct PtrToArg<char32_t> {
-	_FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
-		return char32_t(*reinterpret_cast<const int *>(p_ptr));
-	}
-	_FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
-		*(int *)p_ptr = p_val;
-	}
-};
-#endif
-
 class MethodBind {
 class MethodBind {
 	int method_id;
 	int method_id;
 	uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
 	uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
 	StringName name;
 	StringName name;
+	StringName instance_class;
 	Vector<Variant> default_arguments;
 	Vector<Variant> default_arguments;
 	int default_argument_count = 0;
 	int default_argument_count = 0;
 	int argument_count = 0;
 	int argument_count = 0;
@@ -225,11 +78,11 @@ protected:
 	void set_argument_count(int p_count) { argument_count = p_count; }
 	void set_argument_count(int p_count) { argument_count = p_count; }
 
 
 public:
 public:
-	Vector<Variant> get_default_arguments() const { return default_arguments; }
+	_FORCE_INLINE_ const Vector<Variant> &get_default_arguments() const { return default_arguments; }
 	_FORCE_INLINE_ int get_default_argument_count() const { return default_argument_count; }
 	_FORCE_INLINE_ int get_default_argument_count() const { return default_argument_count; }
 
 
 	_FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
 	_FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
-		int idx = argument_count - p_arg - 1;
+		int idx = p_arg - (argument_count - default_arguments.size());
 
 
 		if (idx < 0 || idx >= default_arguments.size()) {
 		if (idx < 0 || idx >= default_arguments.size()) {
 			return false;
 			return false;
@@ -239,7 +92,7 @@ public:
 	}
 	}
 
 
 	_FORCE_INLINE_ Variant get_default_argument(int p_arg) const {
 	_FORCE_INLINE_ Variant get_default_argument(int p_arg) const {
-		int idx = argument_count - p_arg - 1;
+		int idx = p_arg - (argument_count - default_arguments.size());
 
 
 		if (idx < 0 || idx >= default_arguments.size()) {
 		if (idx < 0 || idx >= default_arguments.size()) {
 			return Variant();
 			return Variant();
@@ -249,7 +102,6 @@ public:
 	}
 	}
 
 
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
-
 	_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
 	_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
 		ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
 		ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
 		return argument_types[p_argument + 1];
 		return argument_types[p_argument + 1];
@@ -258,15 +110,16 @@ public:
 	PropertyInfo get_argument_info(int p_argument) const;
 	PropertyInfo get_argument_info(int p_argument) const;
 	PropertyInfo get_return_info() const;
 	PropertyInfo get_return_info() const;
 
 
-	void set_argument_names(const Vector<StringName> &p_names); //set by class, db, can't be inferred otherwise
+	void set_argument_names(const Vector<StringName> &p_names); // Set by ClassDB, can't be inferred otherwise.
 	Vector<StringName> get_argument_names() const;
 	Vector<StringName> get_argument_names() const;
 
 
 	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const = 0;
 	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const = 0;
-
 #endif
 #endif
+
 	void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
 	void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
 	uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
 	uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
-	virtual String get_instance_class() const = 0;
+	_FORCE_INLINE_ StringName get_instance_class() const { return instance_class; }
+	_FORCE_INLINE_ void set_instance_class(const StringName &p_class) { instance_class = p_class; }
 
 
 	_FORCE_INLINE_ int get_argument_count() const { return argument_count; };
 	_FORCE_INLINE_ int get_argument_count() const { return argument_count; };
 
 
@@ -302,7 +155,6 @@ protected:
 
 
 public:
 public:
 #ifdef DEBUG_METHODS_ENABLED
 #ifdef DEBUG_METHODS_ENABLED
-
 	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
 	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
 		if (p_arg < 0) {
 		if (p_arg < 0) {
 			return arguments.return_val;
 			return arguments.return_val;
@@ -320,14 +172,12 @@ public:
 	virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
 	virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
 		return GodotTypeInfo::METADATA_NONE;
 		return GodotTypeInfo::METADATA_NONE;
 	}
 	}
-
 #else
 #else
-
 	virtual Variant::Type _gen_argument_type(int p_arg) const {
 	virtual Variant::Type _gen_argument_type(int p_arg) const {
 		return Variant::NIL;
 		return Variant::NIL;
 	}
 	}
-
 #endif
 #endif
+
 	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::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);
 		T *instance = static_cast<T *>(p_object);
 		return (instance->*call_method)(p_args, p_arg_count, r_error);
 		return (instance->*call_method)(p_args, p_arg_count, r_error);
@@ -364,7 +214,6 @@ public:
 
 
 	void set_method(NativeCall p_method) { call_method = p_method; }
 	void set_method(NativeCall p_method) { call_method = p_method; }
 	virtual bool is_const() const { return false; }
 	virtual bool is_const() const { return false; }
-	virtual String get_instance_class() const { return T::get_class_static(); }
 
 
 	virtual bool is_vararg() const { return true; }
 	virtual bool is_vararg() const { return true; }
 
 
@@ -378,16 +227,365 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i
 	MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
 	MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
 	a->set_method(p_method);
 	a->set_method(p_method);
 	a->set_method_info(p_info, p_return_nil_is_variant);
 	a->set_method_info(p_info, p_return_nil_is_variant);
+	a->set_instance_class(T::get_class_static());
 	return a;
 	return a;
 }
 }
 
 
-/** This amazing hack is based on the FastDelegates theory */
-
-// tale of an amazing hack.. //
+/**** VARIADIC TEMPLATES ****/
 
 
-// if you declare a nonexistent class..
+#ifndef TYPED_METHOD_BIND
 class __UnexistingClass;
 class __UnexistingClass;
+#define MB_T __UnexistingClass
+#else
+#define MB_T T
+#endif
 
 
-#include "method_bind.gen.inc"
+// no return, not const
+#ifdef TYPED_METHOD_BIND
+template <class T, class... P>
+#else
+template <class... P>
+#endif
+class MethodBindT : public MethodBind {
+	void (MB_T::*method)(P...);
+
+protected:
+#ifdef DEBUG_METHODS_ENABLED
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			return call_get_argument_type<P...>(p_arg);
+		} else {
+			return Variant::NIL;
+		}
+	}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+		PropertyInfo pi;
+		call_get_argument_type_info<P...>(p_arg, pi);
+		return pi;
+	}
+#endif
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+		return call_get_argument_metadata<P...>(p_arg);
+	}
+
+#endif
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+#ifdef TYPED_METHOD_BIND
+		call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+#else
+		call_with_variant_args_dv((MB_T *)(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+#endif
+		return Variant();
+	}
+
+#ifdef PTRCALL_ENABLED
+	virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+#ifdef TYPED_METHOD_BIND
+		call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args);
+#else
+		call_with_ptr_args<MB_T, P...>((MB_T *)(p_object), method, p_args);
+#endif
+	}
+#endif
+
+	MethodBindT(void (MB_T::*p_method)(P...)) {
+		method = p_method;
+#ifdef DEBUG_METHODS_ENABLED
+		_generate_argument_types(sizeof...(P));
+#endif
+		set_argument_count(sizeof...(P));
+	}
+};
+
+template <class T, class... P>
+MethodBind *create_method_bind(void (T::*p_method)(P...)) {
+#ifdef TYPED_METHOD_BIND
+	MethodBind *a = memnew((MethodBindT<T, P...>)(p_method));
+#else
+	MethodBind *a = memnew((MethodBindT<P...>)(reinterpret_cast<void (MB_T::*)(P...)>(p_method)));
+#endif
+	a->set_instance_class(T::get_class_static());
+	return a;
+}
+
+// no return, not const
+
+#ifdef TYPED_METHOD_BIND
+template <class T, class... P>
+#else
+template <class... P>
+#endif
+class MethodBindTC : public MethodBind {
+	void (MB_T::*method)(P...) const;
+
+protected:
+#ifdef DEBUG_METHODS_ENABLED
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			return call_get_argument_type<P...>(p_arg);
+		} else {
+			return Variant::NIL;
+		}
+	}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+		PropertyInfo pi;
+		call_get_argument_type_info<P...>(p_arg, pi);
+		return pi;
+	}
+#endif
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+		return call_get_argument_metadata<P...>(p_arg);
+	}
+
+#endif
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+#ifdef TYPED_METHOD_BIND
+		call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+#else
+		call_with_variant_argsc_dv((MB_T *)(p_object), method, p_args, p_arg_count, r_error, get_default_arguments());
+#endif
+		return Variant();
+	}
+
+#ifdef PTRCALL_ENABLED
+	virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+#ifdef TYPED_METHOD_BIND
+		call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args);
+#else
+		call_with_ptr_argsc<MB_T, P...>((MB_T *)(p_object), method, p_args);
+#endif
+	}
+#endif
+
+	MethodBindTC(void (MB_T::*p_method)(P...) const) {
+		method = p_method;
+		_set_const(true);
+#ifdef DEBUG_METHODS_ENABLED
+		_generate_argument_types(sizeof...(P));
+#endif
+		set_argument_count(sizeof...(P));
+	}
+};
+
+template <class T, class... P>
+MethodBind *create_method_bind(void (T::*p_method)(P...) const) {
+#ifdef TYPED_METHOD_BIND
+	MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method));
+#else
+	MethodBind *a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::*)(P...) const>(p_method)));
+#endif
+	a->set_instance_class(T::get_class_static());
+	return a;
+}
+
+// return, not const
+
+#ifdef TYPED_METHOD_BIND
+template <class T, class R, class... P>
+#else
+template <class R, class... P>
+#endif
+class MethodBindTR : public MethodBind {
+	R(MB_T::*method)
+	(P...);
+
+protected:
+#ifdef DEBUG_METHODS_ENABLED
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			return call_get_argument_type<P...>(p_arg);
+		} else {
+			return GetTypeInfo<R>::VARIANT_TYPE;
+		}
+	}
+
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			PropertyInfo pi;
+			call_get_argument_type_info<P...>(p_arg, pi);
+			return pi;
+		} else {
+			return GetTypeInfo<R>::get_class_info();
+		}
+	}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+#endif
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+		if (p_arg >= 0) {
+			return call_get_argument_metadata<P...>(p_arg);
+		} else {
+			return GetTypeInfo<R>::METADATA;
+		}
+	}
+#endif
+
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+		Variant ret;
+#ifdef TYPED_METHOD_BIND
+		call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+#else
+		call_with_variant_args_ret_dv((MB_T *)p_object, method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+#endif
+		return ret;
+	}
+
+#ifdef PTRCALL_ENABLED
+	virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+#ifdef TYPED_METHOD_BIND
+		call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
+#else
+		call_with_ptr_args_ret<MB_T, R, P...>((MB_T *)(p_object), method, p_args, r_ret);
+#endif
+	}
+#endif
+
+	MethodBindTR(R (MB_T::*p_method)(P...)) {
+		method = p_method;
+		_set_returns(true);
+#ifdef DEBUG_METHODS_ENABLED
+		_generate_argument_types(sizeof...(P));
+#endif
+		set_argument_count(sizeof...(P));
+	}
+};
+
+template <class T, class R, class... P>
+MethodBind *create_method_bind(R (T::*p_method)(P...)) {
+#ifdef TYPED_METHOD_BIND
+	MethodBind *a = memnew((MethodBindTR<T, R, P...>)(p_method));
+#else
+	MethodBind *a = memnew((MethodBindTR<R, P...>)(reinterpret_cast<R (MB_T::*)(P...)>(p_method)));
+#endif
+
+	a->set_instance_class(T::get_class_static());
+	return a;
+}
+
+// return, const
+
+#ifdef TYPED_METHOD_BIND
+template <class T, class R, class... P>
+#else
+template <class R, class... P>
+#endif
+class MethodBindTRC : public MethodBind {
+	R(MB_T::*method)
+	(P...) const;
+
+protected:
+#ifdef DEBUG_METHODS_ENABLED
+// GCC raises warnings in the case P = {} as the comparison is always false...
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+	virtual Variant::Type _gen_argument_type(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			return call_get_argument_type<P...>(p_arg);
+		} else {
+			return GetTypeInfo<R>::VARIANT_TYPE;
+		}
+	}
+
+	virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
+		if (p_arg >= 0 && p_arg < (int)sizeof...(P)) {
+			PropertyInfo pi;
+			call_get_argument_type_info<P...>(p_arg, pi);
+			return pi;
+		} else {
+			return GetTypeInfo<R>::get_class_info();
+		}
+	}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+#endif
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+	virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+		if (p_arg >= 0) {
+			return call_get_argument_metadata<P...>(p_arg);
+		} else {
+			return GetTypeInfo<R>::METADATA;
+		}
+	}
+#endif
+
+	virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+		Variant ret;
+#ifdef TYPED_METHOD_BIND
+		call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+#else
+		call_with_variant_args_retc_dv((MB_T *)(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments());
+#endif
+		return ret;
+	}
+
+#ifdef PTRCALL_ENABLED
+	virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
+#ifdef TYPED_METHOD_BIND
+		call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret);
+#else
+		call_with_ptr_args_retc<MB_T, R, P...>((MB_T *)(p_object), method, p_args, r_ret);
+#endif
+	}
+#endif
+
+	MethodBindTRC(R (MB_T::*p_method)(P...) const) {
+		method = p_method;
+		_set_returns(true);
+		_set_const(true);
+#ifdef DEBUG_METHODS_ENABLED
+		_generate_argument_types(sizeof...(P));
+#endif
+		set_argument_count(sizeof...(P));
+	}
+};
+
+template <class T, class R, class... P>
+MethodBind *create_method_bind(R (T::*p_method)(P...) const) {
+#ifdef TYPED_METHOD_BIND
+	MethodBind *a = memnew((MethodBindTRC<T, R, P...>)(p_method));
+#else
+	MethodBind *a = memnew((MethodBindTRC<R, P...>)(reinterpret_cast<R (MB_T::*)(P...) const>(p_method)));
+#endif
+	a->set_instance_class(T::get_class_static());
+	return a;
+}
 
 
 #endif // METHOD_BIND_H
 #endif // METHOD_BIND_H

+ 0 - 3
core/object.h

@@ -812,7 +812,4 @@ public:
 	static int get_object_count();
 	static int get_object_count();
 };
 };
 
 
-//needed by macros
-#include "core/class_db.h"
-
 #endif // OBJECT_H
 #endif // OBJECT_H

+ 1 - 1
core/project_settings.h

@@ -31,7 +31,7 @@
 #ifndef PROJECT_SETTINGS_H
 #ifndef PROJECT_SETTINGS_H
 #define PROJECT_SETTINGS_H
 #define PROJECT_SETTINGS_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/os/thread_safe.h"
 #include "core/os/thread_safe.h"
 #include "core/set.h"
 #include "core/set.h"
 
 

+ 0 - 1
core/reference.h

@@ -32,7 +32,6 @@
 #define REFERENCE_H
 #define REFERENCE_H
 
 
 #include "core/class_db.h"
 #include "core/class_db.h"
-#include "core/object.h"
 #include "core/safe_refcount.h"
 #include "core/safe_refcount.h"
 
 
 class Reference : public Object {
 class Reference : public Object {

+ 0 - 1
core/resource.h

@@ -32,7 +32,6 @@
 #define RESOURCE_H
 #define RESOURCE_H
 
 
 #include "core/class_db.h"
 #include "core/class_db.h"
-#include "core/object.h"
 #include "core/reference.h"
 #include "core/reference.h"
 #include "core/safe_refcount.h"
 #include "core/safe_refcount.h"
 #include "core/self_list.h"
 #include "core/self_list.h"

+ 1 - 8
core/type_info.h

@@ -31,7 +31,7 @@
 #ifndef TYPE_INFO_H
 #ifndef TYPE_INFO_H
 #define TYPE_INFO_H
 #define TYPE_INFO_H
 
 
-#ifdef DEBUG_METHODS_ENABLED
+#include "core/typedefs.h"
 
 
 template <bool C, typename T = void>
 template <bool C, typename T = void>
 struct EnableIf {
 struct EnableIf {
@@ -267,11 +267,4 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
 
 
 #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
 #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
 
 
-#else
-
-#define MAKE_ENUM_TYPE_INFO(m_enum)
-#define CLASS_INFO(m_type)
-
-#endif // DEBUG_METHODS_ENABLED
-
 #endif // TYPE_INFO_H
 #endif // TYPE_INFO_H

+ 4 - 0
core/typedefs.h

@@ -263,4 +263,8 @@ struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
 template <size_t... Is>
 template <size_t... Is>
 struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
 struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
 
 
+#ifdef DEBUG_ENABLED
+#define DEBUG_METHODS_ENABLED
+#endif
+
 #endif // TYPEDEFS_H
 #endif // TYPEDEFS_H

+ 1 - 1
core/undo_redo.h

@@ -31,7 +31,7 @@
 #ifndef UNDO_REDO_H
 #ifndef UNDO_REDO_H
 #define UNDO_REDO_H
 #define UNDO_REDO_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/resource.h"
 #include "core/resource.h"
 
 
 class UndoRedo : public Object {
 class UndoRedo : public Object {

+ 10 - 145
core/variant_call.cpp

@@ -30,13 +30,13 @@
 
 
 #include "variant.h"
 #include "variant.h"
 
 
+#include "core/class_db.h"
 #include "core/color_names.inc"
 #include "core/color_names.inc"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/crypto/crypto_core.h"
 #include "core/crypto/crypto_core.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/io/compression.h"
 #include "core/io/compression.h"
 #include "core/oa_hash_map.h"
 #include "core/oa_hash_map.h"
-#include "core/object.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 
 
 _FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {
 _FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {
@@ -96,44 +96,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
-			const Variant **args = p_args;
-#ifdef DEBUG_ENABLED
-			if ((size_t)p_argcount > sizeof...(P)) {
-				r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-				r_error.argument = sizeof...(P);
-				return;
-			}
-#endif
-			if ((size_t)p_argcount < sizeof...(P)) {
-				size_t missing = sizeof...(P) - (size_t)p_argcount;
-				if (missing <= (size_t)default_values.size()) {
-					args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
-					// GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous
-					// conditions, so it raises a warning on the potential use of `i < 0` as the
-					// execution condition.
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
-					for (size_t i = 0; i < sizeof...(P); i++) {
-						if (i < (size_t)p_argcount) {
-							args[i] = p_args[i];
-						} else {
-							args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
-						}
-					}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-				} else {
-#ifdef DEBUG_ENABLED
-					r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-					r_error.argument = sizeof...(P);
-#endif
-					return;
-				}
-			}
-			call_with_variant_args_helper(VariantGetInternalPtr<T>::get_ptr(base), method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
+			call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, default_values);
 		}
 		}
 
 
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@@ -187,11 +150,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual Variant::Type get_return_type() const {
 		virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
 			return GetTypeInfo<R>::VARIANT_TYPE;
 			return GetTypeInfo<R>::VARIANT_TYPE;
-#else
-			return Variant::NIL;
-#endif
 		}
 		}
 		virtual uint32_t get_flags() const {
 		virtual uint32_t get_flags() const {
 			uint32_t f = 0;
 			uint32_t f = 0;
@@ -202,41 +161,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
-			const Variant **args = p_args;
-#ifdef DEBUG_ENABLED
-			if ((size_t)p_argcount > sizeof...(P)) {
-				r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-				r_error.argument = sizeof...(P);
-				return;
-			}
-#endif
-			if ((size_t)p_argcount < sizeof...(P)) {
-				size_t missing = sizeof...(P) - (size_t)p_argcount;
-				if (missing <= (size_t)default_values.size()) {
-					args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
-					for (size_t i = 0; i < sizeof...(P); i++) {
-						if (i < (size_t)p_argcount) {
-							args[i] = p_args[i];
-						} else {
-							args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
-						}
-					}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-				} else {
-#ifdef DEBUG_ENABLED
-					r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-					r_error.argument = sizeof...(P);
-#endif
-					return;
-				}
-			}
-			call_with_variant_args_ret_helper(VariantGetInternalPtr<T>::get_ptr(base), method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+			call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, default_values);
 		}
 		}
 
 
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@@ -288,11 +213,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual Variant::Type get_return_type() const {
 		virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
 			return GetTypeInfo<R>::VARIANT_TYPE;
 			return GetTypeInfo<R>::VARIANT_TYPE;
-#else
-			return Variant::NIL;
-#endif
 		}
 		}
 		virtual uint32_t get_flags() const {
 		virtual uint32_t get_flags() const {
 			uint32_t f = FLAG_IS_CONST;
 			uint32_t f = FLAG_IS_CONST;
@@ -303,44 +224,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
 		virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
-			const Variant **args = p_args;
-#ifdef DEBUG_ENABLED
-			if ((size_t)p_argcount > sizeof...(P)) {
-				r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
-				r_error.argument = sizeof...(P);
-				return;
-			}
-#endif
-			if ((size_t)p_argcount < sizeof...(P)) {
-				size_t missing = sizeof...(P) - (size_t)p_argcount;
-				if (missing <= (size_t)default_values.size()) {
-					args = (const Variant **)alloca(sizeof...(P) * sizeof(const Variant *));
-					// GCC fails to see that `sizeof...(P)` cannot be 0 here given the previous
-					// conditions, so it raises a warning on the potential use of `i < 0` as the
-					// execution condition.
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
-					for (size_t i = 0; i < sizeof...(P); i++) {
-						if (i < (size_t)p_argcount) {
-							args[i] = p_args[i];
-						} else {
-							args[i] = &default_values[i - p_argcount + (default_values.size() - missing)];
-						}
-					}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-				} else {
-#ifdef DEBUG_ENABLED
-					r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
-					r_error.argument = sizeof...(P);
-#endif
-					return;
-				}
-			}
-			call_with_variant_args_retc_helper(VariantGetInternalPtr<T>::get_ptr(base), method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+			call_with_variant_args_retc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, default_values);
 		}
 		}
 
 
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
 		virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@@ -392,11 +276,7 @@ struct _VariantCall {
 		}
 		}
 
 
 		virtual Variant::Type get_return_type() const {
 		virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
 			return GetTypeInfo<R>::VARIANT_TYPE;
 			return GetTypeInfo<R>::VARIANT_TYPE;
-#else
-			return Variant::NIL;
-#endif
 		}
 		}
 		virtual uint32_t get_flags() const {
 		virtual uint32_t get_flags() const {
 			uint32_t f = 0;
 			uint32_t f = 0;
@@ -552,12 +432,8 @@ struct _VariantCall {
 		Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args));
 		Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args));
 #endif
 #endif
 
 
-#ifdef DEBUG_METHODS_ENABLED
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
-		(void)m;
-#endif
 	}
 	}
 
 
 	template <class T, class R, class... P>
 	template <class T, class R, class... P>
@@ -578,12 +454,8 @@ struct _VariantCall {
 		Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args));
 		Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args));
 #endif
 #endif
 
 
-#ifdef DEBUG_METHODS_ENABLED
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
-		(void)m;
-#endif
 	}
 	}
 
 
 	template <class T, class R, class... P>
 	template <class T, class R, class... P>
@@ -603,12 +475,8 @@ struct _VariantCall {
 #else
 #else
 		Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args));
 		Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args));
 #endif
 #endif
-#ifdef DEBUG_METHODS_ENABLED
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
-		(void)m;
-#endif
 	}
 	}
 
 
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
@@ -641,12 +509,8 @@ struct _VariantCall {
 		Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args));
 		Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args));
 #endif
 #endif
 
 
-#ifdef DEBUG_METHODS_ENABLED
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
 		type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
-		(void)m;
-#endif
 	}
 	}
 
 
 #ifdef DEBUG_ENABLED
 #ifdef DEBUG_ENABLED
@@ -1745,6 +1609,7 @@ void register_variant_methods() {
 	bind_method(Color, lightened, sarray("amount"), varray());
 	bind_method(Color, lightened, sarray("amount"), varray());
 	bind_method(Color, darkened, sarray("amount"), varray());
 	bind_method(Color, darkened, sarray("amount"), varray());
 	bind_method(Color, to_html, sarray("with_alpha"), varray(true));
 	bind_method(Color, to_html, sarray("with_alpha"), varray(true));
+	bind_method(Color, blend, sarray("over"), varray());
 
 
 	//Color is immutable, need to probably find a way to do this via constructor
 	//Color is immutable, need to probably find a way to do this via constructor
 	//ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0));
 	//ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0));
@@ -1888,7 +1753,7 @@ void register_variant_methods() {
 	bind_method(Dictionary, hash, sarray(), varray());
 	bind_method(Dictionary, hash, sarray(), varray());
 	bind_method(Dictionary, keys, sarray(), varray());
 	bind_method(Dictionary, keys, sarray(), varray());
 	bind_method(Dictionary, values, sarray(), varray());
 	bind_method(Dictionary, values, sarray(), varray());
-	bind_method(Dictionary, duplicate, sarray("deep"), varray("true"));
+	bind_method(Dictionary, duplicate, sarray("deep"), varray(false));
 	bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
 	bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
 
 
 	/* Array */
 	/* Array */
@@ -1919,7 +1784,7 @@ void register_variant_methods() {
 	bind_method(Array, bsearch, sarray("value", "before"), varray(true));
 	bind_method(Array, bsearch, sarray("value", "before"), varray(true));
 	bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
 	bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
 	bind_method(Array, invert, sarray(), varray());
 	bind_method(Array, invert, sarray(), varray());
-	bind_method(Array, duplicate, sarray("deep"), varray(true));
+	bind_method(Array, duplicate, sarray("deep"), varray(false));
 	bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
 	bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
 	bind_method(Array, max, sarray(), varray());
 	bind_method(Array, max, sarray(), varray());
 	bind_method(Array, min, sarray(), varray());
 	bind_method(Array, min, sarray(), varray());
@@ -1944,9 +1809,9 @@ void register_variant_methods() {
 	bind_function("get_string_from_utf16", _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray());
 	bind_function("get_string_from_utf16", _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray());
 	bind_function("get_string_from_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray());
 	bind_function("get_string_from_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray());
 	bind_function("hex_encode", _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray());
 	bind_function("hex_encode", _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray());
-	bind_function("compress", _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray());
-	bind_function("decompress", _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray());
-	bind_function("decompress_dynamic", _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray());
+	bind_function("compress", _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray(0));
+	bind_function("decompress", _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0));
+	bind_function("decompress_dynamic", _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0));
 
 
 	/* Int32 Array */
 	/* Int32 Array */
 
 

+ 1 - 1
core/variant_op.cpp

@@ -30,9 +30,9 @@
 
 
 #include "variant.h"
 #include "variant.h"
 
 
+#include "core/class_db.h"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/debugger/engine_debugger.h"
 #include "core/debugger/engine_debugger.h"
-#include "core/object.h"
 
 
 #define CASE_TYPE_ALL(PREFIX, OP) \
 #define CASE_TYPE_ALL(PREFIX, OP) \
 	CASE_TYPE(PREFIX, OP, INT)    \
 	CASE_TYPE(PREFIX, OP, INT)    \

+ 1 - 1
editor/editor_plugin.cpp

@@ -791,7 +791,7 @@ bool EditorPlugin::build() {
 	return true;
 	return true;
 }
 }
 
 
-void EditorPlugin::queue_save_layout() const {
+void EditorPlugin::queue_save_layout() {
 	EditorNode::get_singleton()->save_layout();
 	EditorNode::get_singleton()->save_layout();
 }
 }
 
 

+ 1 - 1
editor/editor_plugin.h

@@ -221,7 +221,7 @@ public:
 
 
 	int update_overlays() const;
 	int update_overlays() const;
 
 
-	void queue_save_layout() const;
+	void queue_save_layout();
 
 
 	void make_bottom_panel_item_visible(Control *p_item);
 	void make_bottom_panel_item_visible(Control *p_item);
 	void hide_bottom_panel();
 	void hide_bottom_panel();

+ 0 - 2
editor/editor_resource_preview.cpp

@@ -30,8 +30,6 @@
 
 
 #include "editor_resource_preview.h"
 #include "editor_resource_preview.h"
 
 
-#include "core/method_bind_ext.gen.inc"
-
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
 #include "core/message_queue.h"
 #include "core/message_queue.h"

+ 1 - 2
editor/editor_settings.h

@@ -31,8 +31,7 @@
 #ifndef EDITOR_SETTINGS_H
 #ifndef EDITOR_SETTINGS_H
 #define EDITOR_SETTINGS_H
 #define EDITOR_SETTINGS_H
 
 
-#include "core/object.h"
-
+#include "core/class_db.h"
 #include "core/io/config_file.h"
 #include "core/io/config_file.h"
 #include "core/os/thread_safe.h"
 #include "core/os/thread_safe.h"
 #include "core/resource.h"
 #include "core/resource.h"

+ 1 - 1
editor/editor_vcs_interface.h

@@ -31,7 +31,7 @@
 #ifndef EDITOR_VCS_INTERFACE_H
 #ifndef EDITOR_VCS_INTERFACE_H
 #define EDITOR_VCS_INTERFACE_H
 #define EDITOR_VCS_INTERFACE_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/ustring.h"
 #include "core/ustring.h"
 #include "scene/gui/panel_container.h"
 #include "scene/gui/panel_container.h"
 
 

+ 1 - 1
editor/fileserver/editor_file_server.h

@@ -31,10 +31,10 @@
 #ifndef EDITOR_FILE_SERVER_H
 #ifndef EDITOR_FILE_SERVER_H
 #define EDITOR_FILE_SERVER_H
 #define EDITOR_FILE_SERVER_H
 
 
+#include "core/class_db.h"
 #include "core/io/file_access_network.h"
 #include "core/io/file_access_network.h"
 #include "core/io/packet_peer.h"
 #include "core/io/packet_peer.h"
 #include "core/io/tcp_server.h"
 #include "core/io/tcp_server.h"
-#include "core/object.h"
 #include "core/os/thread.h"
 #include "core/os/thread.h"
 
 
 class EditorFileServer : public Object {
 class EditorFileServer : public Object {

+ 4 - 4
editor/inspector_dock.cpp

@@ -164,7 +164,7 @@ void InspectorDock::_resource_file_selected(String p_file) {
 	editor->push_item(res.operator->());
 	editor->push_item(res.operator->());
 }
 }
 
 
-void InspectorDock::_save_resource(bool save_as) const {
+void InspectorDock::_save_resource(bool save_as) {
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 
 
@@ -179,7 +179,7 @@ void InspectorDock::_save_resource(bool save_as) const {
 	}
 	}
 }
 }
 
 
-void InspectorDock::_unref_resource() const {
+void InspectorDock::_unref_resource() {
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 
 
@@ -190,7 +190,7 @@ void InspectorDock::_unref_resource() const {
 	editor->edit_current();
 	editor->edit_current();
 }
 }
 
 
-void InspectorDock::_copy_resource() const {
+void InspectorDock::_copy_resource() {
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current();
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 	Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
 
 
@@ -201,7 +201,7 @@ void InspectorDock::_copy_resource() const {
 	EditorSettings::get_singleton()->set_resource_clipboard(current_res);
 	EditorSettings::get_singleton()->set_resource_clipboard(current_res);
 }
 }
 
 
-void InspectorDock::_paste_resource() const {
+void InspectorDock::_paste_resource() {
 	RES r = EditorSettings::get_singleton()->get_resource_clipboard();
 	RES r = EditorSettings::get_singleton()->get_resource_clipboard();
 	if (r.is_valid()) {
 	if (r.is_valid()) {
 		editor->push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(), String());
 		editor->push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(), String());

+ 4 - 4
editor/inspector_dock.h

@@ -96,10 +96,10 @@ class InspectorDock : public VBoxContainer {
 	void _load_resource(const String &p_type = "");
 	void _load_resource(const String &p_type = "");
 	void _open_resource_selector() { _load_resource(); }; // just used to call from arg-less signal
 	void _open_resource_selector() { _load_resource(); }; // just used to call from arg-less signal
 	void _resource_file_selected(String p_file);
 	void _resource_file_selected(String p_file);
-	void _save_resource(bool save_as) const;
-	void _unref_resource() const;
-	void _copy_resource() const;
-	void _paste_resource() const;
+	void _save_resource(bool save_as);
+	void _unref_resource();
+	void _copy_resource();
+	void _paste_resource();
 
 
 	void _warning_pressed();
 	void _warning_pressed();
 	void _resource_created();
 	void _resource_created();

+ 1 - 1
main/performance.h

@@ -31,7 +31,7 @@
 #ifndef PERFORMANCE_H
 #ifndef PERFORMANCE_H
 #define PERFORMANCE_H
 #define PERFORMANCE_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/ordered_hash_map.h"
 #include "core/ordered_hash_map.h"
 
 
 #define PERF_WARN_OFFLINE_FUNCTION
 #define PERF_WARN_OFFLINE_FUNCTION

+ 1 - 1
modules/bullet/collision_object_bullet.h

@@ -31,9 +31,9 @@
 #ifndef COLLISION_OBJECT_BULLET_H
 #ifndef COLLISION_OBJECT_BULLET_H
 #define COLLISION_OBJECT_BULLET_H
 #define COLLISION_OBJECT_BULLET_H
 
 
+#include "core/class_db.h"
 #include "core/math/transform.h"
 #include "core/math/transform.h"
 #include "core/math/vector3.h"
 #include "core/math/vector3.h"
-#include "core/object.h"
 #include "core/vset.h"
 #include "core/vset.h"
 #include "shape_owner_bullet.h"
 #include "shape_owner_bullet.h"
 
 

+ 1 - 1
modules/denoise/lightmap_denoiser.h

@@ -31,7 +31,7 @@
 #ifndef LIGHTMAP_DENOISER_H
 #ifndef LIGHTMAP_DENOISER_H
 #define LIGHTMAP_DENOISER_H
 #define LIGHTMAP_DENOISER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "scene/3d/lightmapper.h"
 #include "scene/3d/lightmapper.h"
 
 
 struct OIDNDeviceImpl;
 struct OIDNDeviceImpl;

+ 2 - 1
modules/gdnavigation/rvo_agent.h

@@ -31,8 +31,9 @@
 #ifndef RVO_AGENT_H
 #ifndef RVO_AGENT_H
 #define RVO_AGENT_H
 #define RVO_AGENT_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "nav_rid.h"
 #include "nav_rid.h"
+
 #include <Agent.h>
 #include <Agent.h>
 
 
 /**
 /**

+ 1 - 1
modules/jsonrpc/jsonrpc.h

@@ -31,7 +31,7 @@
 #ifndef GODOT_JSON_RPC_H
 #ifndef GODOT_JSON_RPC_H
 #define GODOT_JSON_RPC_H
 #define GODOT_JSON_RPC_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/variant.h"
 #include "core/variant.h"
 
 
 class JSONRPC : public Object {
 class JSONRPC : public Object {

+ 0 - 1
modules/mono/glue/base_object_glue.cpp

@@ -31,7 +31,6 @@
 #ifdef MONO_GLUE_ENABLED
 #ifdef MONO_GLUE_ENABLED
 
 
 #include "core/class_db.h"
 #include "core/class_db.h"
-#include "core/object.h"
 #include "core/reference.h"
 #include "core/reference.h"
 #include "core/string_name.h"
 #include "core/string_name.h"
 
 

+ 0 - 1
modules/mono/glue/glue_header.h

@@ -64,7 +64,6 @@ void godot_register_glue_header_icalls() {
 #include "core/engine.h"
 #include "core/engine.h"
 #include "core/method_bind.h"
 #include "core/method_bind.h"
 #include "core/node_path.h"
 #include "core/node_path.h"
-#include "core/object.h"
 #include "core/reference.h"
 #include "core/reference.h"
 #include "core/typedefs.h"
 #include "core/typedefs.h"
 #include "core/ustring.h"
 #include "core/ustring.h"

+ 1 - 1
modules/mono/glue/rid_glue.cpp

@@ -30,7 +30,7 @@
 
 
 #ifdef MONO_GLUE_ENABLED
 #ifdef MONO_GLUE_ENABLED
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/resource.h"
 #include "core/resource.h"
 #include "core/rid.h"
 #include "core/rid.h"
 
 

+ 1 - 1
modules/mono/mono_gd/gd_mono_internals.h

@@ -35,7 +35,7 @@
 
 
 #include "../utils/macros.h"
 #include "../utils/macros.h"
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 namespace GDMonoInternals {
 namespace GDMonoInternals {
 
 

+ 1 - 1
modules/mono/mono_gd/gd_mono_utils.h

@@ -37,7 +37,7 @@
 #include "../utils/macros.h"
 #include "../utils/macros.h"
 #include "gd_mono_header.h"
 #include "gd_mono_header.h"
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/reference.h"
 #include "core/reference.h"
 
 
 #define UNHANDLED_EXCEPTION(m_exc)                     \
 #define UNHANDLED_EXCEPTION(m_exc)                     \

+ 1 - 1
modules/visual_script/visual_script_editor.cpp

@@ -30,8 +30,8 @@
 
 
 #include "visual_script_editor.h"
 #include "visual_script_editor.h"
 
 
+#include "core/class_db.h"
 #include "core/input/input.h"
 #include "core/input/input.h"
-#include "core/object.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/script_language.h"
 #include "core/script_language.h"
 #include "core/variant.h"
 #include "core/variant.h"

+ 1 - 1
platform/iphone/game_center.h

@@ -33,7 +33,7 @@
 #ifndef GAME_CENTER_H
 #ifndef GAME_CENTER_H
 #define GAME_CENTER_H
 #define GAME_CENTER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 class GameCenter : public Object {
 class GameCenter : public Object {
 	GDCLASS(GameCenter, Object);
 	GDCLASS(GameCenter, Object);

+ 1 - 1
platform/iphone/icloud.h

@@ -33,7 +33,7 @@
 #ifndef ICLOUD_H
 #ifndef ICLOUD_H
 #define ICLOUD_H
 #define ICLOUD_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 class ICloud : public Object {
 class ICloud : public Object {
 	GDCLASS(ICloud, Object);
 	GDCLASS(ICloud, Object);

+ 1 - 1
platform/iphone/in_app_store.h

@@ -33,7 +33,7 @@
 #ifndef IN_APP_STORE_H
 #ifndef IN_APP_STORE_H
 #define IN_APP_STORE_H
 #define IN_APP_STORE_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 class InAppStore : public Object {
 class InAppStore : public Object {
 	GDCLASS(InAppStore, Object);
 	GDCLASS(InAppStore, Object);

+ 1 - 1
platform/iphone/ios.h

@@ -31,7 +31,7 @@
 #ifndef IOS_H
 #ifndef IOS_H
 #define IOS_H
 #define IOS_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 class iOS : public Object {
 class iOS : public Object {
 	GDCLASS(iOS, Object);
 	GDCLASS(iOS, Object);

+ 1 - 1
platform/javascript/api/javascript_eval.h

@@ -31,7 +31,7 @@
 #ifndef JAVASCRIPT_EVAL_H
 #ifndef JAVASCRIPT_EVAL_H
 #define JAVASCRIPT_EVAL_H
 #define JAVASCRIPT_EVAL_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 
 
 class JavaScript : public Object {
 class JavaScript : public Object {
 private:
 private:

+ 2 - 1
platform/osx/detect.py

@@ -139,7 +139,8 @@ def configure(env):
         env.Append(CPPDEFINES=["__MACPORTS__"])  # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
         env.Append(CPPDEFINES=["__MACPORTS__"])  # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
 
 
     if env["CXX"] == "clang++":
     if env["CXX"] == "clang++":
-        env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
+        # This should now work with clang++, re-enable if there are issues
+        # env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
         env["CC"] = "clang"
         env["CC"] = "clang"
         env["LINK"] = "clang++"
         env["LINK"] = "clang++"
 
 

+ 2 - 1
platform/uwp/export/export.cpp

@@ -29,11 +29,12 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "export.h"
 #include "export.h"
+
 #include "core/bind/core_bind.h"
 #include "core/bind/core_bind.h"
+#include "core/class_db.h"
 #include "core/crypto/crypto_core.h"
 #include "core/crypto/crypto_core.h"
 #include "core/io/marshalls.h"
 #include "core/io/marshalls.h"
 #include "core/io/zip_io.h"
 #include "core/io/zip_io.h"
-#include "core/object.h"
 #include "core/os/dir_access.h"
 #include "core/os/dir_access.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"

+ 1 - 2
scene/2d/physics_body_2d.cpp

@@ -30,12 +30,11 @@
 
 
 #include "physics_body_2d.h"
 #include "physics_body_2d.h"
 
 
+#include "core/class_db.h"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/engine.h"
 #include "core/engine.h"
 #include "core/list.h"
 #include "core/list.h"
 #include "core/math/math_funcs.h"
 #include "core/math/math_funcs.h"
-#include "core/method_bind_ext.gen.inc"
-#include "core/object.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"
 
 

+ 0 - 1
scene/2d/tile_map.cpp

@@ -32,7 +32,6 @@
 
 
 #include "collision_object_2d.h"
 #include "collision_object_2d.h"
 #include "core/io/marshalls.h"
 #include "core/io/marshalls.h"
-#include "core/method_bind_ext.gen.inc"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "scene/2d/area_2d.h"
 #include "scene/2d/area_2d.h"
 #include "servers/navigation_server_2d.h"
 #include "servers/navigation_server_2d.h"

+ 0 - 1
scene/3d/gi_probe.cpp

@@ -32,7 +32,6 @@
 
 
 #include "core/os/os.h"
 #include "core/os/os.h"
 
 
-#include "core/method_bind_ext.gen.inc"
 #include "mesh_instance_3d.h"
 #include "mesh_instance_3d.h"
 #include "voxelizer.h"
 #include "voxelizer.h"
 
 

+ 1 - 2
scene/3d/physics_body_3d.cpp

@@ -30,11 +30,10 @@
 
 
 #include "physics_body_3d.h"
 #include "physics_body_3d.h"
 
 
+#include "core/class_db.h"
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/engine.h"
 #include "core/engine.h"
 #include "core/list.h"
 #include "core/list.h"
-#include "core/method_bind_ext.gen.inc"
-#include "core/object.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "scene/3d/collision_shape_3d.h"
 #include "scene/3d/collision_shape_3d.h"
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"

+ 1 - 1
scene/3d/soft_body_3d.cpp

@@ -30,8 +30,8 @@
 
 
 #include "soft_body_3d.h"
 #include "soft_body_3d.h"
 
 
+#include "core/class_db.h"
 #include "core/list.h"
 #include "core/list.h"
-#include "core/object.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "scene/3d/collision_object_3d.h"
 #include "scene/3d/collision_object_3d.h"

+ 0 - 1
scene/animation/animation_tree.cpp

@@ -32,7 +32,6 @@
 
 
 #include "animation_blend_tree.h"
 #include "animation_blend_tree.h"
 #include "core/engine.h"
 #include "core/engine.h"
-#include "core/method_bind_ext.gen.inc"
 #include "scene/scene_string_names.h"
 #include "scene/scene_string_names.h"
 #include "servers/audio/audio_stream.h"
 #include "servers/audio/audio_stream.h"
 
 

+ 0 - 2
scene/animation/tween.cpp

@@ -30,8 +30,6 @@
 
 
 #include "tween.h"
 #include "tween.h"
 
 
-#include "core/method_bind_ext.gen.inc"
-
 void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8, const Variant &p_arg9, const Variant &p_arg10) {
 void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8, const Variant &p_arg9, const Variant &p_arg10) {
 	// Add a new pending command and reference it
 	// Add a new pending command and reference it
 	pending_commands.push_back(PendingCommand());
 	pending_commands.push_back(PendingCommand());

+ 1 - 1
scene/debugger/scene_debugger.h

@@ -32,7 +32,7 @@
 #define SCENE_DEBUGGER_H
 #define SCENE_DEBUGGER_H
 
 
 #include "core/array.h"
 #include "core/array.h"
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/pair.h"
 #include "core/pair.h"
 #include "core/ustring.h"
 #include "core/ustring.h"
 
 

+ 0 - 2
scene/gui/graph_node.cpp

@@ -30,8 +30,6 @@
 
 
 #include "graph_node.h"
 #include "graph_node.h"
 
 
-#include "core/method_bind_ext.gen.inc"
-
 bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
 bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
 	if (!p_name.operator String().begins_with("slot/")) {
 	if (!p_name.operator String().begins_with("slot/")) {
 		return false;
 		return false;

+ 0 - 1
scene/main/canvas_item.cpp

@@ -32,7 +32,6 @@
 
 
 #include "core/input/input.h"
 #include "core/input/input.h"
 #include "core/message_queue.h"
 #include "core/message_queue.h"
-#include "core/method_bind_ext.gen.inc"
 #include "scene/main/canvas_layer.h"
 #include "scene/main/canvas_layer.h"
 #include "scene/main/viewport.h"
 #include "scene/main/viewport.h"
 #include "scene/main/window.h"
 #include "scene/main/window.h"

+ 0 - 1
scene/main/node.h

@@ -34,7 +34,6 @@
 #include "core/class_db.h"
 #include "core/class_db.h"
 #include "core/map.h"
 #include "core/map.h"
 #include "core/node_path.h"
 #include "core/node_path.h"
-#include "core/object.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 #include "core/script_language.h"
 #include "core/script_language.h"
 #include "core/typed_array.h"
 #include "core/typed_array.h"

+ 0 - 1
scene/resources/font.cpp

@@ -31,7 +31,6 @@
 #include "font.h"
 #include "font.h"
 
 
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
-#include "core/method_bind_ext.gen.inc"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 
 
 void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate, const Color &p_outline_modulate) const {
 void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate, const Color &p_outline_modulate) const {

+ 0 - 2
scene/resources/surface_tool.cpp

@@ -30,8 +30,6 @@
 
 
 #include "surface_tool.h"
 #include "surface_tool.h"
 
 
-#include "core/method_bind_ext.gen.inc"
-
 #define _VERTEX_SNAP 0.0001
 #define _VERTEX_SNAP 0.0001
 #define EQ_VERTEX_DIST 0.00001
 #define EQ_VERTEX_DIST 0.00001
 
 

+ 0 - 1
scene/resources/texture.cpp

@@ -32,7 +32,6 @@
 
 
 #include "core/core_string_names.h"
 #include "core/core_string_names.h"
 #include "core/io/image_loader.h"
 #include "core/io/image_loader.h"
-#include "core/method_bind_ext.gen.inc"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "mesh.h"
 #include "mesh.h"
 #include "scene/resources/bit_map.h"
 #include "scene/resources/bit_map.h"

+ 1 - 1
servers/audio_server.h

@@ -31,8 +31,8 @@
 #ifndef AUDIO_SERVER_H
 #ifndef AUDIO_SERVER_H
 #define AUDIO_SERVER_H
 #define AUDIO_SERVER_H
 
 
+#include "core/class_db.h"
 #include "core/math/audio_frame.h"
 #include "core/math/audio_frame.h"
-#include "core/object.h"
 #include "core/os/os.h"
 #include "core/os/os.h"
 #include "core/variant.h"
 #include "core/variant.h"
 #include "servers/audio/audio_effect.h"
 #include "servers/audio/audio_effect.h"

+ 1 - 1
servers/camera_server.h

@@ -31,7 +31,7 @@
 #ifndef CAMERA_SERVER_H
 #ifndef CAMERA_SERVER_H
 #define CAMERA_SERVER_H
 #define CAMERA_SERVER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/os/thread_safe.h"
 #include "core/os/thread_safe.h"
 #include "core/reference.h"
 #include "core/reference.h"
 #include "core/rid.h"
 #include "core/rid.h"

+ 0 - 1
servers/display_server.cpp

@@ -31,7 +31,6 @@
 #include "display_server.h"
 #include "display_server.h"
 
 
 #include "core/input/input.h"
 #include "core/input/input.h"
-#include "core/method_bind_ext.gen.inc"
 #include "scene/resources/texture.h"
 #include "scene/resources/texture.h"
 
 
 DisplayServer *DisplayServer::singleton = nullptr;
 DisplayServer *DisplayServer::singleton = nullptr;

+ 1 - 1
servers/navigation_server_2d.h

@@ -35,7 +35,7 @@
 #ifndef NAVIGATION_2D_SERVER_H
 #ifndef NAVIGATION_2D_SERVER_H
 #define NAVIGATION_2D_SERVER_H
 #define NAVIGATION_2D_SERVER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "scene/2d/navigation_region_2d.h"
 #include "scene/2d/navigation_region_2d.h"
 
 

+ 1 - 1
servers/navigation_server_3d.h

@@ -35,7 +35,7 @@
 #ifndef NAVIGATION_SERVER_H
 #ifndef NAVIGATION_SERVER_H
 #define NAVIGATION_SERVER_H
 #define NAVIGATION_SERVER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "scene/3d/navigation_region_3d.h"
 #include "scene/3d/navigation_region_3d.h"
 
 

+ 0 - 1
servers/physics_server_2d.cpp

@@ -30,7 +30,6 @@
 
 
 #include "physics_server_2d.h"
 #include "physics_server_2d.h"
 
 
-#include "core/method_bind_ext.gen.inc"
 #include "core/print_string.h"
 #include "core/print_string.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 
 

+ 1 - 1
servers/physics_server_2d.h

@@ -31,7 +31,7 @@
 #ifndef PHYSICS_2D_SERVER_H
 #ifndef PHYSICS_2D_SERVER_H
 #define PHYSICS_2D_SERVER_H
 #define PHYSICS_2D_SERVER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/reference.h"
 #include "core/reference.h"
 #include "core/resource.h"
 #include "core/resource.h"
 
 

+ 0 - 1
servers/physics_server_3d.cpp

@@ -30,7 +30,6 @@
 
 
 #include "physics_server_3d.h"
 #include "physics_server_3d.h"
 
 
-#include "core/method_bind_ext.gen.inc"
 #include "core/print_string.h"
 #include "core/print_string.h"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 
 

+ 1 - 1
servers/physics_server_3d.h

@@ -31,7 +31,7 @@
 #ifndef PHYSICS_SERVER_H
 #ifndef PHYSICS_SERVER_H
 #define PHYSICS_SERVER_H
 #define PHYSICS_SERVER_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/resource.h"
 #include "core/resource.h"
 
 
 class PhysicsDirectSpaceState3D;
 class PhysicsDirectSpaceState3D;

+ 1 - 1
servers/rendering/rendering_device.cpp

@@ -29,7 +29,7 @@
 /*************************************************************************/
 /*************************************************************************/
 
 
 #include "rendering_device.h"
 #include "rendering_device.h"
-#include "core/method_bind_ext.gen.inc"
+
 #include "rendering_device_binds.h"
 #include "rendering_device_binds.h"
 
 
 RenderingDevice *RenderingDevice::singleton = nullptr;
 RenderingDevice *RenderingDevice::singleton = nullptr;

+ 1 - 1
servers/rendering/rendering_device.h

@@ -31,7 +31,7 @@
 #ifndef RENDERING_DEVICE_H
 #ifndef RENDERING_DEVICE_H
 #define RENDERING_DEVICE_H
 #define RENDERING_DEVICE_H
 
 
-#include "core/object.h"
+#include "core/class_db.h"
 #include "core/typed_array.h"
 #include "core/typed_array.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
 
 

+ 0 - 1
servers/rendering_server.cpp

@@ -30,7 +30,6 @@
 
 
 #include "rendering_server.h"
 #include "rendering_server.h"
 
 
-#include "core/method_bind_ext.gen.inc"
 #include "core/project_settings.h"
 #include "core/project_settings.h"
 
 
 RenderingServer *RenderingServer::singleton = nullptr;
 RenderingServer *RenderingServer::singleton = nullptr;

+ 1 - 1
servers/rendering_server.h

@@ -31,10 +31,10 @@
 #ifndef RENDERING_SERVER_H
 #ifndef RENDERING_SERVER_H
 #define RENDERING_SERVER_H
 #define RENDERING_SERVER_H
 
 
+#include "core/class_db.h"
 #include "core/image.h"
 #include "core/image.h"
 #include "core/math/geometry_3d.h"
 #include "core/math/geometry_3d.h"
 #include "core/math/transform_2d.h"
 #include "core/math/transform_2d.h"
-#include "core/object.h"
 #include "core/rid.h"
 #include "core/rid.h"
 #include "core/typed_array.h"
 #include "core/typed_array.h"
 #include "core/variant.h"
 #include "core/variant.h"

+ 1 - 0
tests/test_main.cpp

@@ -42,6 +42,7 @@
 #include "test_gui.h"
 #include "test_gui.h"
 #include "test_list.h"
 #include "test_list.h"
 #include "test_math.h"
 #include "test_math.h"
+#include "test_method_bind.h"
 #include "test_oa_hash_map.h"
 #include "test_oa_hash_map.h"
 #include "test_ordered_hash_map.h"
 #include "test_ordered_hash_map.h"
 #include "test_physics_2d.h"
 #include "test_physics_2d.h"

+ 165 - 0
tests/test_method_bind.h

@@ -0,0 +1,165 @@
+/*************************************************************************/
+/*  test_method_bind.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 TEST_METHOD_BIND_H
+#define TEST_METHOD_BIND_H
+
+#include "core/class_db.h"
+
+#include "tests/test_macros.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <wchar.h>
+
+namespace TestMethodBind {
+
+class MethodBindTester : public Object {
+	GDCLASS(MethodBindTester, Object);
+
+public:
+	enum Test {
+		TEST_METHOD,
+		TEST_METHOD_ARGS,
+		TEST_METHODC,
+		TEST_METHODC_ARGS,
+		TEST_METHODR,
+		TEST_METHODR_ARGS,
+		TEST_METHODRC,
+		TEST_METHODRC_ARGS,
+		TEST_METHOD_DEFARGS,
+		TEST_MAX
+	};
+
+	int test_num = 0;
+
+	bool test_valid[TEST_MAX];
+
+	void test_method() {
+		test_valid[TEST_METHOD] = true;
+	}
+
+	void test_method_args(int p_arg) {
+		test_valid[TEST_METHOD_ARGS] = p_arg == test_num;
+	}
+
+	void test_methodc() {
+		test_valid[TEST_METHODC] = true;
+	}
+
+	void test_methodc_args(int p_arg) {
+		test_valid[TEST_METHODC_ARGS] = p_arg == test_num;
+	}
+
+	int test_methodr() {
+		test_valid[TEST_METHODR] = true; //temporary
+		return test_num;
+	}
+
+	int test_methodr_args(int p_arg) {
+		test_valid[TEST_METHODR_ARGS] = true; //temporary
+		return p_arg;
+	}
+
+	int test_methodrc() {
+		test_valid[TEST_METHODRC] = true; //temporary
+		return test_num;
+	}
+
+	int test_methodrc_args(int p_arg) {
+		test_valid[TEST_METHODRC_ARGS] = true; //temporary
+		return p_arg;
+	}
+
+	void test_method_default_args(int p_arg1, int p_arg2, int p_arg3, int p_arg4, int p_arg5) {
+		test_valid[TEST_METHOD_DEFARGS] = p_arg1 == 1 && p_arg2 == 2 && p_arg3 == 3 && p_arg4 == 4 && p_arg5 == 5; //temporary
+	}
+
+	static void _bind_methods() {
+		ClassDB::bind_method(D_METHOD("test_method"), &MethodBindTester::test_method);
+		ClassDB::bind_method(D_METHOD("test_method_args"), &MethodBindTester::test_method_args);
+		ClassDB::bind_method(D_METHOD("test_methodc"), &MethodBindTester::test_methodc);
+		ClassDB::bind_method(D_METHOD("test_methodc_args"), &MethodBindTester::test_methodc_args);
+		ClassDB::bind_method(D_METHOD("test_methodr"), &MethodBindTester::test_methodr);
+		ClassDB::bind_method(D_METHOD("test_methodr_args"), &MethodBindTester::test_methodr_args);
+		ClassDB::bind_method(D_METHOD("test_methodrc"), &MethodBindTester::test_methodrc);
+		ClassDB::bind_method(D_METHOD("test_methodrc_args"), &MethodBindTester::test_methodrc_args);
+		ClassDB::bind_method(D_METHOD("test_method_default_args"), &MethodBindTester::test_method_default_args, DEFVAL(9) /* wrong on purpose */, DEFVAL(4), DEFVAL(5));
+	}
+
+	virtual void run_tests() {
+		for (int i = 0; i < TEST_MAX; i++) {
+			test_valid[i] = false;
+		}
+		//regular
+		test_num = Math::rand();
+		call("test_method");
+		test_num = Math::rand();
+		call("test_method_args", test_num);
+		test_num = Math::rand();
+		call("test_methodc");
+		test_num = Math::rand();
+		call("test_methodc_args", test_num);
+		//return
+		test_num = Math::rand();
+		test_valid[TEST_METHODR] = int(call("test_methodr")) == test_num && test_valid[TEST_METHODR];
+		test_num = Math::rand();
+		test_valid[TEST_METHODR_ARGS] = int(call("test_methodr_args", test_num)) == test_num && test_valid[TEST_METHODR_ARGS];
+		test_num = Math::rand();
+		test_valid[TEST_METHODRC] = int(call("test_methodrc")) == test_num && test_valid[TEST_METHODRC];
+		test_num = Math::rand();
+		test_valid[TEST_METHODRC_ARGS] = int(call("test_methodrc_args", test_num)) == test_num && test_valid[TEST_METHODRC_ARGS];
+
+		call("test_method_default_args", 1, 2, 3, 4);
+	}
+};
+
+TEST_CASE("[MethodBind] check all method binds") {
+	MethodBindTester *mbt = memnew(MethodBindTester);
+
+	print_line("testing method bind");
+	mbt->run_tests();
+
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_ARGS]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODC]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODC_ARGS]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODR]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODR_ARGS]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC_ARGS]);
+	CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_DEFARGS]);
+
+	memdelete(mbt);
+}
+
+} // namespace TestMethodBind
+
+#endif // TEST_METHOD_BIND_H