Refactor MethodBind to use variadic templates

Removed make_binders and the old style generated binders.
This commit is contained in:
reduz 2020-10-15 12:29:59 -03:00 committed by Juan Linietsky
parent 5b6a22e275
commit ee06a70ea6
77 changed files with 1263 additions and 1098 deletions

View File

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

View File

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

657
core/binder_common.h Normal file
View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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())

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,13 +30,13 @@
#include "variant.h" #include "variant.h"
#include "core/class_db.h"
#include "core/color_names.inc" #include "core/color_names.inc"
#include "core/core_string_names.h" #include "core/core_string_names.h"
#include "core/crypto/crypto_core.h" #include "core/crypto/crypto_core.h"
#include "core/debugger/engine_debugger.h" #include "core/debugger/engine_debugger.h"
#include "core/io/compression.h" #include "core/io/compression.h"
#include "core/oa_hash_map.h" #include "core/oa_hash_map.h"
#include "core/object.h"
#include "core/os/os.h" #include "core/os/os.h"
_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) { _FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) {
@ -96,44 +96,7 @@ struct _VariantCall {
} }
virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
const Variant **args = p_args; call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, 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
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)>{});
} }
virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@ -187,11 +150,7 @@ struct _VariantCall {
} }
virtual Variant::Type get_return_type() const { virtual Variant::Type get_return_type() const {
#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE; return GetTypeInfo<R>::VARIANT_TYPE;
#else
return Variant::NIL;
#endif
} }
virtual uint32_t get_flags() const { virtual uint32_t get_flags() const {
uint32_t f = 0; uint32_t f = 0;
@ -202,41 +161,7 @@ struct _VariantCall {
} }
virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
const Variant **args = p_args; call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, 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
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)>{});
} }
virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@ -288,11 +213,7 @@ struct _VariantCall {
} }
virtual Variant::Type get_return_type() const { virtual Variant::Type get_return_type() const {
#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE; return GetTypeInfo<R>::VARIANT_TYPE;
#else
return Variant::NIL;
#endif
} }
virtual uint32_t get_flags() const { virtual uint32_t get_flags() const {
uint32_t f = FLAG_IS_CONST; uint32_t f = FLAG_IS_CONST;
@ -303,44 +224,7 @@ struct _VariantCall {
} }
virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { virtual void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
const Variant **args = p_args; call_with_variant_args_retc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, 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
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)>{});
} }
virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) {
@ -392,11 +276,7 @@ struct _VariantCall {
} }
virtual Variant::Type get_return_type() const { virtual Variant::Type get_return_type() const {
#ifdef DEBUG_METHODS_ENABLED
return GetTypeInfo<R>::VARIANT_TYPE; return GetTypeInfo<R>::VARIANT_TYPE;
#else
return Variant::NIL;
#endif
} }
virtual uint32_t get_flags() const { virtual uint32_t get_flags() const {
uint32_t f = 0; uint32_t f = 0;
@ -552,12 +432,8 @@ struct _VariantCall {
Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args)); Variant::InternalMethod *m = memnew((InternalMethod<T, P...>)(p_method, p_default_args));
#endif #endif
#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
#else
(void)m;
#endif
} }
template <class T, class R, class... P> template <class T, class R, class... P>
@ -578,12 +454,8 @@ struct _VariantCall {
Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args)); Variant::InternalMethod *m = memnew((InternalMethodRC<T, R, P...>)(p_method, p_default_args));
#endif #endif
#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
#else
(void)m;
#endif
} }
template <class T, class R, class... P> template <class T, class R, class... P>
@ -603,12 +475,8 @@ struct _VariantCall {
#else #else
Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args)); Variant::InternalMethod *m = memnew((InternalMethodR<T, R, P...>)(p_method, p_default_args));
#endif #endif
#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
#else
(void)m;
#endif
} }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
@ -641,12 +509,8 @@ struct _VariantCall {
Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args)); Variant::InternalMethod *m = memnew((InternalMethodRS<T, R, P...>)(p_method, p_default_args));
#endif #endif
#ifdef DEBUG_METHODS_ENABLED
type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m); type_internal_methods[GetTypeInfo<T>::VARIANT_TYPE].insert(p_name, m);
type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name); type_internal_method_names[GetTypeInfo<T>::VARIANT_TYPE].push_back(p_name);
#else
(void)m;
#endif
} }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
@ -1745,6 +1609,7 @@ void register_variant_methods() {
bind_method(Color, lightened, sarray("amount"), varray()); bind_method(Color, lightened, sarray("amount"), varray());
bind_method(Color, darkened, sarray("amount"), varray()); bind_method(Color, darkened, sarray("amount"), varray());
bind_method(Color, to_html, sarray("with_alpha"), varray(true)); bind_method(Color, to_html, sarray("with_alpha"), varray(true));
bind_method(Color, blend, sarray("over"), varray());
//Color is immutable, need to probably find a way to do this via constructor //Color is immutable, need to probably find a way to do this via constructor
//ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0));
@ -1888,7 +1753,7 @@ void register_variant_methods() {
bind_method(Dictionary, hash, sarray(), varray()); bind_method(Dictionary, hash, sarray(), varray());
bind_method(Dictionary, keys, sarray(), varray()); bind_method(Dictionary, keys, sarray(), varray());
bind_method(Dictionary, values, sarray(), varray()); bind_method(Dictionary, values, sarray(), varray());
bind_method(Dictionary, duplicate, sarray("deep"), varray("true")); bind_method(Dictionary, duplicate, sarray("deep"), varray(false));
bind_method(Dictionary, get, sarray("key", "default"), varray(Variant())); bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
/* Array */ /* Array */
@ -1919,7 +1784,7 @@ void register_variant_methods() {
bind_method(Array, bsearch, sarray("value", "before"), varray(true)); bind_method(Array, bsearch, sarray("value", "before"), varray(true));
bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true)); bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
bind_method(Array, invert, sarray(), varray()); bind_method(Array, invert, sarray(), varray());
bind_method(Array, duplicate, sarray("deep"), varray(true)); bind_method(Array, duplicate, sarray("deep"), varray(false));
bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
bind_method(Array, max, sarray(), varray()); bind_method(Array, max, sarray(), varray());
bind_method(Array, min, sarray(), varray()); bind_method(Array, min, sarray(), varray());
@ -1944,9 +1809,9 @@ void register_variant_methods() {
bind_function("get_string_from_utf16", _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray()); bind_function("get_string_from_utf16", _VariantCall::func_PackedByteArray_get_string_from_utf16, sarray(), varray());
bind_function("get_string_from_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray()); bind_function("get_string_from_utf32", _VariantCall::func_PackedByteArray_get_string_from_utf32, sarray(), varray());
bind_function("hex_encode", _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray()); bind_function("hex_encode", _VariantCall::func_PackedByteArray_hex_encode, sarray(), varray());
bind_function("compress", _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray()); bind_function("compress", _VariantCall::func_PackedByteArray_compress, sarray("compression_mode"), varray(0));
bind_function("decompress", _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray()); 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()); bind_function("decompress_dynamic", _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0));
/* Int32 Array */ /* Int32 Array */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

165
tests/test_method_bind.h Normal file
View File

@ -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