diff options
79 files changed, 1267 insertions, 1101 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) \ diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 623e4b099b..2e8b76865d 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -834,6 +834,7 @@ </member> <member name="name" type="StringName" setter="set_name" getter="get_name"> The name of the node. This name is unique among the siblings (other child nodes from the same parent). When set to an existing name, the node will be automatically renamed. + [b]Note:[/b] Auto-generated names might include the [code]@[/code] character, which is reserved for unique names when using [method add_child]. When setting the name manually, any [code]@[/code] will be removed. </member> <member name="owner" type="Node" setter="set_owner" getter="get_owner"> The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using [PackedScene]), all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing. diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 082c317655..e330713cfb 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -791,7 +791,7 @@ bool EditorPlugin::build() { return true; } -void EditorPlugin::queue_save_layout() const { +void EditorPlugin::queue_save_layout() { EditorNode::get_singleton()->save_layout(); } diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 40a91cbfb9..dd3bf08678 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -221,7 +221,7 @@ public: int update_overlays() const; - void queue_save_layout() const; + void queue_save_layout(); void make_bottom_panel_item_visible(Control *p_item); void hide_bottom_panel(); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 3170ea5ff8..9723ae188b 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -30,8 +30,6 @@ #include "editor_resource_preview.h" -#include "core/method_bind_ext.gen.inc" - #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/message_queue.h" diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 04bb49bb51..c1bb7951fa 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -31,8 +31,7 @@ #ifndef EDITOR_SETTINGS_H #define EDITOR_SETTINGS_H -#include "core/object.h" - +#include "core/class_db.h" #include "core/io/config_file.h" #include "core/os/thread_safe.h" #include "core/resource.h" diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index ee9e51441d..6ef55f0a46 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -31,7 +31,7 @@ #ifndef EDITOR_VCS_INTERFACE_H #define EDITOR_VCS_INTERFACE_H -#include "core/object.h" +#include "core/class_db.h" #include "core/ustring.h" #include "scene/gui/panel_container.h" diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 9645fbf39e..eefaa503c1 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -31,10 +31,10 @@ #ifndef EDITOR_FILE_SERVER_H #define EDITOR_FILE_SERVER_H +#include "core/class_db.h" #include "core/io/file_access_network.h" #include "core/io/packet_peer.h" #include "core/io/tcp_server.h" -#include "core/object.h" #include "core/os/thread.h" class EditorFileServer : public Object { diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 8f1b8838d8..c88cd8ea5f 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -164,7 +164,7 @@ void InspectorDock::_resource_file_selected(String p_file) { 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(); 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(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; @@ -190,7 +190,7 @@ void InspectorDock::_unref_resource() const { editor->edit_current(); } -void InspectorDock::_copy_resource() const { +void InspectorDock::_copy_resource() { ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); 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); } -void InspectorDock::_paste_resource() const { +void InspectorDock::_paste_resource() { RES r = EditorSettings::get_singleton()->get_resource_clipboard(); if (r.is_valid()) { editor->push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(), String()); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 551d3d1643..b2dabf19c5 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -96,10 +96,10 @@ class InspectorDock : public VBoxContainer { void _load_resource(const String &p_type = ""); void _open_resource_selector() { _load_resource(); }; // just used to call from arg-less signal 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 _resource_created(); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 4f627b1d0c..e4a384449b 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPATIAL_EDITOR_PLUGIN_H -#define SPATIAL_EDITOR_PLUGIN_H +#ifndef NODE_3D_EDITOR_PLUGIN_H +#define NODE_3D_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -890,4 +890,4 @@ public: virtual ~EditorNode3DGizmoPlugin(); }; -#endif +#endif // NODE_3D_EDITOR_PLUGIN_H diff --git a/main/performance.h b/main/performance.h index 5f88a24c0f..f406433cf2 100644 --- a/main/performance.h +++ b/main/performance.h @@ -31,7 +31,7 @@ #ifndef PERFORMANCE_H #define PERFORMANCE_H -#include "core/object.h" +#include "core/class_db.h" #include "core/ordered_hash_map.h" #define PERF_WARN_OFFLINE_FUNCTION diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index f1423a69e4..36b3a9550c 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -31,9 +31,9 @@ #ifndef COLLISION_OBJECT_BULLET_H #define COLLISION_OBJECT_BULLET_H +#include "core/class_db.h" #include "core/math/transform.h" #include "core/math/vector3.h" -#include "core/object.h" #include "core/vset.h" #include "shape_owner_bullet.h" diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h index d01bbd10a5..74a9d8af86 100644 --- a/modules/denoise/lightmap_denoiser.h +++ b/modules/denoise/lightmap_denoiser.h @@ -31,7 +31,7 @@ #ifndef LIGHTMAP_DENOISER_H #define LIGHTMAP_DENOISER_H -#include "core/object.h" +#include "core/class_db.h" #include "scene/3d/lightmapper.h" struct OIDNDeviceImpl; diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h index f5c579ba84..1ad9d3ed76 100644 --- a/modules/gdnavigation/rvo_agent.h +++ b/modules/gdnavigation/rvo_agent.h @@ -31,8 +31,9 @@ #ifndef RVO_AGENT_H #define RVO_AGENT_H -#include "core/object.h" +#include "core/class_db.h" #include "nav_rid.h" + #include <Agent.h> /** diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h index e2b7ab0975..6f3f8003e0 100644 --- a/modules/jsonrpc/jsonrpc.h +++ b/modules/jsonrpc/jsonrpc.h @@ -31,7 +31,7 @@ #ifndef GODOT_JSON_RPC_H #define GODOT_JSON_RPC_H -#include "core/object.h" +#include "core/class_db.h" #include "core/variant.h" class JSONRPC : public Object { diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index ebcd6d5e9c..439fb1ab0a 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -31,7 +31,6 @@ #ifdef MONO_GLUE_ENABLED #include "core/class_db.h" -#include "core/object.h" #include "core/reference.h" #include "core/string_name.h" diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index c1f1936711..dc3bf47838 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -64,7 +64,6 @@ void godot_register_glue_header_icalls() { #include "core/engine.h" #include "core/method_bind.h" #include "core/node_path.h" -#include "core/object.h" #include "core/reference.h" #include "core/typedefs.h" #include "core/ustring.h" diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp index 6d2e6b559f..a7b18c36dd 100644 --- a/modules/mono/glue/rid_glue.cpp +++ b/modules/mono/glue/rid_glue.cpp @@ -30,7 +30,7 @@ #ifdef MONO_GLUE_ENABLED -#include "core/object.h" +#include "core/class_db.h" #include "core/resource.h" #include "core/rid.h" diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 038d17f782..cf7efdecd6 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -35,7 +35,7 @@ #include "../utils/macros.h" -#include "core/object.h" +#include "core/class_db.h" namespace GDMonoInternals { diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 5958bf3cc1..80569cb1c7 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -37,7 +37,7 @@ #include "../utils/macros.h" #include "gd_mono_header.h" -#include "core/object.h" +#include "core/class_db.h" #include "core/reference.h" #define UNHANDLED_EXCEPTION(m_exc) \ diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index b1d8c05d87..d962d91287 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -30,8 +30,8 @@ #include "visual_script_editor.h" +#include "core/class_db.h" #include "core/input/input.h" -#include "core/object.h" #include "core/os/keyboard.h" #include "core/script_language.h" #include "core/variant.h" diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h index 6705674ac6..10c8ef52fb 100644 --- a/platform/iphone/game_center.h +++ b/platform/iphone/game_center.h @@ -33,7 +33,7 @@ #ifndef GAME_CENTER_H #define GAME_CENTER_H -#include "core/object.h" +#include "core/class_db.h" class GameCenter : public Object { GDCLASS(GameCenter, Object); diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h index 381edfa718..6ca1e6594a 100644 --- a/platform/iphone/icloud.h +++ b/platform/iphone/icloud.h @@ -33,7 +33,7 @@ #ifndef ICLOUD_H #define ICLOUD_H -#include "core/object.h" +#include "core/class_db.h" class ICloud : public Object { GDCLASS(ICloud, Object); diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h index beb58af2c7..ccf31876a9 100644 --- a/platform/iphone/in_app_store.h +++ b/platform/iphone/in_app_store.h @@ -33,7 +33,7 @@ #ifndef IN_APP_STORE_H #define IN_APP_STORE_H -#include "core/object.h" +#include "core/class_db.h" class InAppStore : public Object { GDCLASS(InAppStore, Object); diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index 2b29e6f268..6a89cd38cb 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -31,7 +31,7 @@ #ifndef IOS_H #define IOS_H -#include "core/object.h" +#include "core/class_db.h" class iOS : public Object { GDCLASS(iOS, Object); diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h index 29229de8e3..26b5b9e484 100644 --- a/platform/javascript/api/javascript_eval.h +++ b/platform/javascript/api/javascript_eval.h @@ -31,7 +31,7 @@ #ifndef JAVASCRIPT_EVAL_H #define JAVASCRIPT_EVAL_H -#include "core/object.h" +#include "core/class_db.h" class JavaScript : public Object { private: diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 6fc1dc65af..50e9bd2653 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -139,7 +139,8 @@ def configure(env): env.Append(CPPDEFINES=["__MACPORTS__"]) # hack to fix libvpx MM256_BROADCASTSI128_SI256 define 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["LINK"] = "clang++" diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 219174b509..e9e536837f 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -29,11 +29,12 @@ /*************************************************************************/ #include "export.h" + #include "core/bind/core_bind.h" +#include "core/class_db.h" #include "core/crypto/crypto_core.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" -#include "core/object.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/project_settings.h" diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 320b382676..402eac644f 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -30,12 +30,11 @@ #include "physics_body_2d.h" +#include "core/class_db.h" #include "core/core_string_names.h" #include "core/engine.h" #include "core/list.h" #include "core/math/math_funcs.h" -#include "core/method_bind_ext.gen.inc" -#include "core/object.h" #include "core/rid.h" #include "scene/scene_string_names.h" diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index c2951559a4..94ec0998fa 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -32,7 +32,6 @@ #include "collision_object_2d.h" #include "core/io/marshalls.h" -#include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "scene/2d/area_2d.h" #include "servers/navigation_server_2d.h" diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index ab30d2fec5..fd592012f8 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -32,7 +32,6 @@ #include "core/os/os.h" -#include "core/method_bind_ext.gen.inc" #include "mesh_instance_3d.h" #include "voxelizer.h" diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index aae81c6a34..579088b835 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -30,11 +30,10 @@ #include "physics_body_3d.h" +#include "core/class_db.h" #include "core/core_string_names.h" #include "core/engine.h" #include "core/list.h" -#include "core/method_bind_ext.gen.inc" -#include "core/object.h" #include "core/rid.h" #include "scene/3d/collision_shape_3d.h" #include "scene/scene_string_names.h" diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 018a2a7a39..3b5c328e43 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -30,8 +30,8 @@ #include "soft_body_3d.h" +#include "core/class_db.h" #include "core/list.h" -#include "core/object.h" #include "core/os/os.h" #include "core/rid.h" #include "scene/3d/collision_object_3d.h" diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index d7d55b468e..bb5d536600 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -32,7 +32,6 @@ #include "animation_blend_tree.h" #include "core/engine.h" -#include "core/method_bind_ext.gen.inc" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index bd4396d680..1a2a97ada8 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -30,8 +30,6 @@ #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) { // Add a new pending command and reference it pending_commands.push_back(PendingCommand()); diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index a2bafde039..80e329f1f2 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -32,7 +32,7 @@ #define SCENE_DEBUGGER_H #include "core/array.h" -#include "core/object.h" +#include "core/class_db.h" #include "core/pair.h" #include "core/ustring.h" diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 38bf31830f..4454e87017 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -30,8 +30,6 @@ #include "graph_node.h" -#include "core/method_bind_ext.gen.inc" - bool GraphNode::_set(const StringName &p_name, const Variant &p_value) { if (!p_name.operator String().begins_with("slot/")) { return false; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 0d9d9d6356..718d805bdd 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -32,7 +32,6 @@ #include "core/input/input.h" #include "core/message_queue.h" -#include "core/method_bind_ext.gen.inc" #include "scene/main/canvas_layer.h" #include "scene/main/viewport.h" #include "scene/main/window.h" diff --git a/scene/main/node.h b/scene/main/node.h index 2928466cd0..09943d0626 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -34,7 +34,6 @@ #include "core/class_db.h" #include "core/map.h" #include "core/node_path.h" -#include "core/object.h" #include "core/project_settings.h" #include "core/script_language.h" #include "core/typed_array.h" diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 7cc39f661d..b75657c2c2 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -31,7 +31,6 @@ #include "font.h" #include "core/io/resource_loader.h" -#include "core/method_bind_ext.gen.inc" #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 { diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 1a2dcc84bb..ff14a5a292 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -30,8 +30,6 @@ #include "surface_tool.h" -#include "core/method_bind_ext.gen.inc" - #define _VERTEX_SNAP 0.0001 #define EQ_VERTEX_DIST 0.00001 diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 39237e1a33..6291d2dddb 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -32,7 +32,6 @@ #include "core/core_string_names.h" #include "core/io/image_loader.h" -#include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "mesh.h" #include "scene/resources/bit_map.h" diff --git a/servers/audio_server.h b/servers/audio_server.h index 80e244aacd..31537e8326 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -31,8 +31,8 @@ #ifndef AUDIO_SERVER_H #define AUDIO_SERVER_H +#include "core/class_db.h" #include "core/math/audio_frame.h" -#include "core/object.h" #include "core/os/os.h" #include "core/variant.h" #include "servers/audio/audio_effect.h" diff --git a/servers/camera_server.h b/servers/camera_server.h index b268553fe5..7723e30974 100644 --- a/servers/camera_server.h +++ b/servers/camera_server.h @@ -31,7 +31,7 @@ #ifndef CAMERA_SERVER_H #define CAMERA_SERVER_H -#include "core/object.h" +#include "core/class_db.h" #include "core/os/thread_safe.h" #include "core/reference.h" #include "core/rid.h" diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 356f4b884a..e678c6919b 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -31,7 +31,6 @@ #include "display_server.h" #include "core/input/input.h" -#include "core/method_bind_ext.gen.inc" #include "scene/resources/texture.h" DisplayServer *DisplayServer::singleton = nullptr; diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index d7384bae74..6575426e73 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -35,7 +35,7 @@ #ifndef NAVIGATION_2D_SERVER_H #define NAVIGATION_2D_SERVER_H -#include "core/object.h" +#include "core/class_db.h" #include "core/rid.h" #include "scene/2d/navigation_region_2d.h" diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index c34bd2391b..7a3e4f5f8f 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -35,7 +35,7 @@ #ifndef NAVIGATION_SERVER_H #define NAVIGATION_SERVER_H -#include "core/object.h" +#include "core/class_db.h" #include "core/rid.h" #include "scene/3d/navigation_region_3d.h" diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 0dac08015f..4338a6938a 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -30,7 +30,6 @@ #include "physics_server_2d.h" -#include "core/method_bind_ext.gen.inc" #include "core/print_string.h" #include "core/project_settings.h" diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index f609adccf9..40773e4ced 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_2D_SERVER_H #define PHYSICS_2D_SERVER_H -#include "core/object.h" +#include "core/class_db.h" #include "core/reference.h" #include "core/resource.h" diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 33a2b91902..d0266f95b5 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -30,7 +30,6 @@ #include "physics_server_3d.h" -#include "core/method_bind_ext.gen.inc" #include "core/print_string.h" #include "core/project_settings.h" diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index b779942460..d79dc6fec0 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -31,7 +31,7 @@ #ifndef PHYSICS_SERVER_H #define PHYSICS_SERVER_H -#include "core/object.h" +#include "core/class_db.h" #include "core/resource.h" class PhysicsDirectSpaceState3D; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 83cbfb85bd..1259b161bd 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "rendering_device.h" -#include "core/method_bind_ext.gen.inc" + #include "rendering_device_binds.h" RenderingDevice *RenderingDevice::singleton = nullptr; diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 72afc7c621..6df66e7b20 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -31,7 +31,7 @@ #ifndef RENDERING_DEVICE_H #define RENDERING_DEVICE_H -#include "core/object.h" +#include "core/class_db.h" #include "core/typed_array.h" #include "servers/display_server.h" diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index fa0834e210..b53415ed20 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -30,7 +30,6 @@ #include "rendering_server.h" -#include "core/method_bind_ext.gen.inc" #include "core/project_settings.h" RenderingServer *RenderingServer::singleton = nullptr; diff --git a/servers/rendering_server.h b/servers/rendering_server.h index dfb3dad166..fce528a764 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -31,10 +31,10 @@ #ifndef RENDERING_SERVER_H #define RENDERING_SERVER_H +#include "core/class_db.h" #include "core/image.h" #include "core/math/geometry_3d.h" #include "core/math/transform_2d.h" -#include "core/object.h" #include "core/rid.h" #include "core/typed_array.h" #include "core/variant.h" diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 60674c79c0..871c796513 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -42,6 +42,7 @@ #include "test_gui.h" #include "test_list.h" #include "test_math.h" +#include "test_method_bind.h" #include "test_oa_hash_map.h" #include "test_ordered_hash_map.h" #include "test_physics_2d.h" diff --git a/tests/test_method_bind.h b/tests/test_method_bind.h new file mode 100644 index 0000000000..f4004c2090 --- /dev/null +++ b/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 |