summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-10-18 14:26:18 +0200
committerGitHub <noreply@github.com>2020-10-18 14:26:18 +0200
commit8f2b7aecee64a2445bfec2221a415a3a92e30211 (patch)
treee4798d05d32d0180357c78aa3fd5a19edbef4991 /core
parent6a8dfdb60e6ab47ee023c62a31cdd754e16d1ca5 (diff)
parentee06a70ea6ac51aa451d55c92b807346458822d7 (diff)
Merge pull request #42826 from reduz/refactor-method-bind
Refactor MethodBind to use variadic templates
Diffstat (limited to 'core')
-rw-r--r--core/SCsub22
-rw-r--r--core/array.cpp2
-rw-r--r--core/binder_common.h657
-rw-r--r--core/callable_method_pointer.h288
-rw-r--r--core/class_db.cpp2
-rw-r--r--core/class_db.h2
-rw-r--r--core/debugger/remote_debugger.h2
-rw-r--r--core/global_constants.cpp2
-rw-r--r--core/input/input_map.h2
-rw-r--r--core/io/packet_peer.h2
-rw-r--r--core/make_binders.py390
-rw-r--r--core/message_queue.h2
-rw-r--r--core/method_bind.h532
-rw-r--r--core/object.h3
-rw-r--r--core/project_settings.h2
-rw-r--r--core/reference.h1
-rw-r--r--core/resource.h1
-rw-r--r--core/type_info.h9
-rw-r--r--core/typedefs.h4
-rw-r--r--core/undo_redo.h2
-rw-r--r--core/variant_call.cpp155
-rw-r--r--core/variant_op.cpp2
22 files changed, 1052 insertions, 1032 deletions
diff --git a/core/SCsub b/core/SCsub
index 59fe63b4b3..b9f06d12ae 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -3,7 +3,6 @@
Import("env")
import core_builders
-import make_binders
env.core_sources = []
@@ -87,11 +86,7 @@ if env["builtin_zlib"]:
# Minizip library, could be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
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]
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."),
)
-# 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
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
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
env.Depends("#core/donors.gen.h", "../DONORS.md")
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
diff --git a/core/array.cpp b/core/array.cpp
index 3c6c8e768b..c6e90d71ec 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -31,8 +31,8 @@
#include "array.h"
#include "container_type_validate.h"
+#include "core/class_db.h"
#include "core/hashfuncs.h"
-#include "core/object.h"
#include "core/script_language.h"
#include "core/variant.h"
#include "core/vector.h"
diff --git a/core/binder_common.h b/core/binder_common.h
new file mode 100644
index 0000000000..0fbfa56230
--- /dev/null
+++ b/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
diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h
index a2275452b4..2007b9f338 100644
--- a/core/callable_method_pointer.h
+++ b/core/callable_method_pointer.h
@@ -31,12 +31,12 @@
#ifndef CALLABLE_METHOD_POINTER_H
#define CALLABLE_METHOD_POINTER_H
+#include "core/binder_common.h"
#include "core/callable.h"
#include "core/hashfuncs.h"
#include "core/object.h"
#include "core/os/copymem.h"
#include "core/simple_type.h"
-#include "core/variant_internal.h"
class CallableCustomMethodPointerBase : public CallableCustom {
uint32_t *comp_ptr;
@@ -70,219 +70,6 @@ public:
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>
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
struct Data {
@@ -338,35 +125,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
// 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>
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
struct Data {
@@ -423,35 +181,6 @@ Callable create_custom_callable_function_pointer(T *p_instance,
// 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>
class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
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)
#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
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 88f1df3457..ad85cd0d62 100644
--- a/core/class_db.cpp
+++ b/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);
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);
diff --git a/core/class_db.h b/core/class_db.h
index 86ac2aa001..4734b06c7a 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -36,7 +36,7 @@
#include "core/print_string.h"
/** 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.
diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h
index dc7e4436e1..320ee15996 100644
--- a/core/debugger/remote_debugger.h
+++ b/core/debugger/remote_debugger.h
@@ -32,10 +32,10 @@
#define REMOTE_DEBUGGER_H
#include "core/array.h"
+#include "core/class_db.h"
#include "core/debugger/debugger_marshalls.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/remote_debugger_peer.h"
-#include "core/object.h"
#include "core/string_name.h"
#include "core/ustring.h"
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index b30685539a..064c302341 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -30,8 +30,8 @@
#include "global_constants.h"
+#include "core/class_db.h"
#include "core/input/input_event.h"
-#include "core/object.h"
#include "core/os/keyboard.h"
#include "core/variant.h"
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 548553ed31..755df26984 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -31,8 +31,8 @@
#ifndef INPUT_MAP_H
#define INPUT_MAP_H
+#include "core/class_db.h"
#include "core/input/input_event.h"
-#include "core/object.h"
class InputMap : public Object {
GDCLASS(InputMap, Object);
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index 92cdbc4151..fb4dc181db 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -31,8 +31,8 @@
#ifndef PACKET_PEER_H
#define PACKET_PEER_H
+#include "core/class_db.h"
#include "core/io/stream_peer.h"
-#include "core/object.h"
#include "core/ring_buffer.h"
class PacketPeer : public Reference {
diff --git a/core/make_binders.py b/core/make_binders.py
deleted file mode 100644
index 7d0d08cde6..0000000000
--- a/core/make_binders.py
+++ /dev/null
@@ -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())
diff --git a/core/message_queue.h b/core/message_queue.h
index 710a605371..5d39ceee03 100644
--- a/core/message_queue.h
+++ b/core/message_queue.h
@@ -31,7 +31,7 @@
#ifndef MESSAGE_QUEUE_H
#define MESSAGE_QUEUE_H
-#include "core/object.h"
+#include "core/class_db.h"
#include "core/os/thread_safe.h"
class MessageQueue {
diff --git a/core/method_bind.h b/core/method_bind.h
index 942e2e0036..d43186257b 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -31,18 +31,7 @@
#ifndef 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 {
@@ -57,151 +46,15 @@ enum MethodFlags {
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
-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 {
int method_id;
uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
StringName name;
+ StringName instance_class;
Vector<Variant> default_arguments;
int default_argument_count = 0;
int argument_count = 0;
@@ -225,11 +78,11 @@ protected:
void set_argument_count(int p_count) { argument_count = p_count; }
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_ 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()) {
return false;
@@ -239,7 +92,7 @@ public:
}
_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()) {
return Variant();
@@ -249,7 +102,6 @@ public:
}
#ifdef DEBUG_METHODS_ENABLED
-
_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
return argument_types[p_argument + 1];
@@ -258,15 +110,16 @@ public:
PropertyInfo get_argument_info(int p_argument) 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;
virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const = 0;
-
#endif
+
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); }
- 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; };
@@ -302,7 +155,6 @@ protected:
public:
#ifdef DEBUG_METHODS_ENABLED
-
virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
if (p_arg < 0) {
return arguments.return_val;
@@ -320,14 +172,12 @@ public:
virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
return GodotTypeInfo::METADATA_NONE;
}
-
#else
-
virtual Variant::Type _gen_argument_type(int p_arg) const {
return Variant::NIL;
}
-
#endif
+
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
T *instance = static_cast<T *>(p_object);
return (instance->*call_method)(p_args, p_arg_count, r_error);
@@ -364,7 +214,6 @@ public:
void set_method(NativeCall p_method) { call_method = p_method; }
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; }
@@ -378,16 +227,365 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i
MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
a->set_method(p_method);
a->set_method_info(p_info, p_return_nil_is_variant);
+ a->set_instance_class(T::get_class_static());
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;
+#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
diff --git a/core/object.h b/core/object.h
index f600e597ec..765fb63c6e 100644
--- a/core/object.h
+++ b/core/object.h
@@ -812,7 +812,4 @@ public:
static int get_object_count();
};
-//needed by macros
-#include "core/class_db.h"
-
#endif // OBJECT_H
diff --git a/core/project_settings.h b/core/project_settings.h
index 6cbb02d30e..9a1d9cee97 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -31,7 +31,7 @@
#ifndef PROJECT_SETTINGS_H
#define PROJECT_SETTINGS_H
-#include "core/object.h"
+#include "core/class_db.h"
#include "core/os/thread_safe.h"
#include "core/set.h"
diff --git a/core/reference.h b/core/reference.h
index f5794b0b67..868894aad4 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -32,7 +32,6 @@
#define REFERENCE_H
#include "core/class_db.h"
-#include "core/object.h"
#include "core/safe_refcount.h"
class Reference : public Object {
diff --git a/core/resource.h b/core/resource.h
index 7699d48735..41707f216d 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -32,7 +32,6 @@
#define RESOURCE_H
#include "core/class_db.h"
-#include "core/object.h"
#include "core/reference.h"
#include "core/safe_refcount.h"
#include "core/self_list.h"
diff --git a/core/type_info.h b/core/type_info.h
index 3c7f59bb84..b9ae88d97c 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -31,7 +31,7 @@
#ifndef TYPE_INFO_H
#define TYPE_INFO_H
-#ifdef DEBUG_METHODS_ENABLED
+#include "core/typedefs.h"
template <bool C, typename T = void>
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())
-#else
-
-#define MAKE_ENUM_TYPE_INFO(m_enum)
-#define CLASS_INFO(m_type)
-
-#endif // DEBUG_METHODS_ENABLED
-
#endif // TYPE_INFO_H
diff --git a/core/typedefs.h b/core/typedefs.h
index 4bfa5debac..2472e5fcd9 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -263,4 +263,8 @@ struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
template <size_t... Is>
struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
+#ifdef DEBUG_ENABLED
+#define DEBUG_METHODS_ENABLED
+#endif
+
#endif // TYPEDEFS_H
diff --git a/core/undo_redo.h b/core/undo_redo.h
index b46f7ff867..68a553efd4 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -31,7 +31,7 @@
#ifndef UNDO_REDO_H
#define UNDO_REDO_H
-#include "core/object.h"
+#include "core/class_db.h"
#include "core/resource.h"
class UndoRedo : public Object {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 06d4cf63b8..66c1987a58 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -30,13 +30,13 @@
#include "variant.h"
+#include "core/class_db.h"
#include "core/color_names.inc"
#include "core/core_string_names.h"
#include "core/crypto/crypto_core.h"
#include "core/debugger/engine_debugger.h"
#include "core/io/compression.h"
#include "core/oa_hash_map.h"
-#include "core/object.h"
#include "core/os/os.h"
_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) {
- 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) {
@@ -187,11 +150,7 @@ struct _VariantCall {
}
virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE;
-#else
- return Variant::NIL;
-#endif
}
virtual uint32_t get_flags() const {
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) {
- 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) {
@@ -288,11 +213,7 @@ struct _VariantCall {
}
virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE;
-#else
- return Variant::NIL;
-#endif
}
virtual uint32_t get_flags() 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) {
- 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) {
@@ -392,11 +276,7 @@ struct _VariantCall {
}
virtual Variant::Type get_return_type() const {
-#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE;
-#else
- return Variant::NIL;
-#endif
}
virtual uint32_t get_flags() const {
uint32_t f = 0;
@@ -552,12 +432,8 @@ struct _VariantCall {
Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args));
#endif
-#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
- (void)m;
-#endif
}
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));
#endif
-#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
- (void)m;
-#endif
}
template <class T, class R, class... P>
@@ -603,12 +475,8 @@ struct _VariantCall {
#else
Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args));
#endif
-#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
- (void)m;
-#endif
}
#ifdef DEBUG_ENABLED
@@ -641,12 +509,8 @@ struct _VariantCall {
Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args));
#endif
-#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
-#else
- (void)m;
-#endif
}
#ifdef DEBUG_ENABLED
@@ -1745,6 +1609,7 @@ void register_variant_methods() {
bind_method(Color, lightened, sarray("amount"), varray());
bind_method(Color, darkened, sarray("amount"), varray());
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
//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, keys, 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()));
/* Array */
@@ -1919,7 +1784,7 @@ void register_variant_methods() {
bind_method(Array, bsearch, sarray("value", "before"), varray(true));
bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
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, max, 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_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, 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 */
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 533b056f91..47539df856 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -30,9 +30,9 @@
#include "variant.h"
+#include "core/class_db.h"
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
-#include "core/object.h"
#define CASE_TYPE_ALL(PREFIX, OP) \
CASE_TYPE(PREFIX, OP, INT) \