Add support for default arguments in utility functions
Co-authored-by: Leo Belda <leo.belda@wanadoo.fr>
This commit is contained in:
parent
3978628c6c
commit
bf4ff9b792
|
@ -580,14 +580,20 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
|
||||||
bool vararg = Variant::is_utility_function_vararg(name);
|
bool vararg = Variant::is_utility_function_vararg(name);
|
||||||
func["is_vararg"] = Variant::is_utility_function_vararg(name);
|
func["is_vararg"] = Variant::is_utility_function_vararg(name);
|
||||||
func["hash"] = Variant::get_utility_function_hash(name);
|
func["hash"] = Variant::get_utility_function_hash(name);
|
||||||
|
|
||||||
Array arguments;
|
Array arguments;
|
||||||
|
const Vector<Variant> def_args = Variant::get_utility_function_default_arguments(name);
|
||||||
int argcount = Variant::get_utility_function_argument_count(name);
|
int argcount = Variant::get_utility_function_argument_count(name);
|
||||||
for (int i = 0; i < argcount; i++) {
|
for (int i = 0; i < argcount; i++) {
|
||||||
Dictionary arg;
|
Dictionary arg;
|
||||||
String argname = vararg ? "arg" + itos(i + 1) : Variant::get_utility_function_argument_name(name, i);
|
String argname = vararg ? "arg" + itos(i + 1) : Variant::get_utility_function_argument_name(name, i);
|
||||||
arg["name"] = argname;
|
arg["name"] = argname;
|
||||||
arg["type"] = get_builtin_or_variant_type_name(Variant::get_utility_function_argument_type(name, i));
|
arg["type"] = get_builtin_or_variant_type_name(Variant::get_utility_function_argument_type(name, i));
|
||||||
//no default value support in utility functions
|
|
||||||
|
const int dargidx = Variant::get_utility_function_default_argument_index(name, i);
|
||||||
|
if (dargidx >= 0) {
|
||||||
|
arg["default_value"] = def_args[dargidx].get_construct_string();
|
||||||
|
}
|
||||||
arguments.push_back(arg);
|
arguments.push_back(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -551,7 +551,7 @@ public:
|
||||||
static uint32_t rand();
|
static uint32_t rand();
|
||||||
static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
|
static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; }
|
||||||
static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
|
static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; }
|
||||||
static double randfn(double mean, double deviation);
|
static double randfn(double mean = 0.0, double deviation = 1.0);
|
||||||
|
|
||||||
static double random(double from, double to);
|
static double random(double from, double to);
|
||||||
static float random(float from, float to);
|
static float random(float from, float to);
|
||||||
|
|
|
@ -752,6 +752,8 @@ public:
|
||||||
static int get_utility_function_argument_count(const StringName &p_name);
|
static int get_utility_function_argument_count(const StringName &p_name);
|
||||||
static Variant::Type get_utility_function_argument_type(const StringName &p_name, int p_arg);
|
static Variant::Type get_utility_function_argument_type(const StringName &p_name, int p_arg);
|
||||||
static String get_utility_function_argument_name(const StringName &p_name, int p_arg);
|
static String get_utility_function_argument_name(const StringName &p_name, int p_arg);
|
||||||
|
static Vector<Variant> get_utility_function_default_arguments(const StringName &p_name);
|
||||||
|
static int get_utility_function_default_argument_index(const StringName &p_name, int p_arg);
|
||||||
static bool has_utility_function_return_value(const StringName &p_name);
|
static bool has_utility_function_return_value(const StringName &p_name);
|
||||||
static Variant::Type get_utility_function_return_type(const StringName &p_name);
|
static Variant::Type get_utility_function_return_type(const StringName &p_name);
|
||||||
static bool is_utility_function_vararg(const StringName &p_name);
|
static bool is_utility_function_vararg(const StringName &p_name);
|
||||||
|
|
|
@ -1228,47 +1228,19 @@ bool VariantUtilityFunctions::is_same(const Variant &p_a, const Variant &p_b) {
|
||||||
return p_a.identity_compare(p_b);
|
return p_a.identity_compare(p_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
|
||||||
#define VCALLR *ret = p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...)
|
|
||||||
#define VCALL p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...)
|
|
||||||
#else
|
|
||||||
#define VCALLR *ret = p_func(VariantCaster<P>::cast(*p_args[Is])...)
|
|
||||||
#define VCALL p_func(VariantCaster<P>::cast(*p_args[Is])...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename R, typename... P, size_t... Is>
|
|
||||||
static _FORCE_INLINE_ void call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
|
|
||||||
r_error.error = Callable::CallError::CALL_OK;
|
|
||||||
VCALLR;
|
|
||||||
(void)p_args; // avoid gcc warning
|
|
||||||
(void)r_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename R, typename... P, size_t... Is>
|
|
||||||
static _FORCE_INLINE_ void validated_call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, IndexSequence<Is...>) {
|
|
||||||
*ret = p_func(VariantCaster<P>::cast(*p_args[Is])...);
|
|
||||||
(void)p_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename R, typename... P, size_t... Is>
|
|
||||||
static _FORCE_INLINE_ void ptr_call_helperpr(R (*p_func)(P...), void *ret, const void **p_args, IndexSequence<Is...>) {
|
|
||||||
PtrToArg<R>::encode(p_func(PtrToArg<P>::convert(p_args[Is])...), ret);
|
|
||||||
(void)p_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename R, typename... P>
|
template <typename R, typename... P>
|
||||||
static _FORCE_INLINE_ void call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error) {
|
static _FORCE_INLINE_ void call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
|
||||||
call_helperpr(p_func, ret, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
call_with_variant_args_static_ret_dv(p_func, p_args, p_argcount, *ret, r_error, p_defvals);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename... P>
|
template <typename R, typename... P>
|
||||||
static _FORCE_INLINE_ void validated_call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args) {
|
static _FORCE_INLINE_ void validated_call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args) {
|
||||||
validated_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_validated_variant_args_static_method_ret(p_func, p_args, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename... P>
|
template <typename R, typename... P>
|
||||||
static _FORCE_INLINE_ void ptr_call_helperr(R (*p_func)(P...), void *ret, const void **p_args) {
|
static _FORCE_INLINE_ void ptr_call_helperr(R (*p_func)(P...), void *ret, const void **p_args) {
|
||||||
ptr_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_ptr_args_static_method_ret<R, P...>(p_func, p_args, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename R, typename... P>
|
template <typename R, typename... P>
|
||||||
|
@ -1288,20 +1260,6 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helperr(R (*p_func)(P...)) {
|
||||||
|
|
||||||
// WITHOUT RET
|
// WITHOUT RET
|
||||||
|
|
||||||
template <typename... P, size_t... Is>
|
|
||||||
static _FORCE_INLINE_ void call_helperp(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
|
|
||||||
r_error.error = Callable::CallError::CALL_OK;
|
|
||||||
VCALL;
|
|
||||||
(void)p_args;
|
|
||||||
(void)r_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... P, size_t... Is>
|
|
||||||
static _FORCE_INLINE_ void validated_call_helperp(void (*p_func)(P...), const Variant **p_args, IndexSequence<Is...>) {
|
|
||||||
p_func(VariantCaster<P>::cast(*p_args[Is])...);
|
|
||||||
(void)p_args;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... P, size_t... Is>
|
template <typename... P, size_t... Is>
|
||||||
static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p_args, IndexSequence<Is...>) {
|
static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p_args, IndexSequence<Is...>) {
|
||||||
p_func(PtrToArg<P>::convert(p_args[Is])...);
|
p_func(PtrToArg<P>::convert(p_args[Is])...);
|
||||||
|
@ -1309,18 +1267,18 @@ static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... P>
|
template <typename... P>
|
||||||
static _FORCE_INLINE_ void call_helper(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error) {
|
static _FORCE_INLINE_ void call_helper(void (*p_func)(P...), const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
|
||||||
call_helperp(p_func, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
call_with_variant_args_static_dv(p_func, p_args, p_argcount, r_error, p_defvals);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... P>
|
template <typename... P>
|
||||||
static _FORCE_INLINE_ void validated_call_helper(void (*p_func)(P...), const Variant **p_args) {
|
static _FORCE_INLINE_ void validated_call_helper(void (*p_func)(P...), const Variant **p_args) {
|
||||||
validated_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_validated_variant_args_static_method(p_func, p_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... P>
|
template <typename... P>
|
||||||
static _FORCE_INLINE_ void ptr_call_helper(void (*p_func)(P...), const void **p_args) {
|
static _FORCE_INLINE_ void ptr_call_helper(void (*p_func)(P...), const void **p_args) {
|
||||||
ptr_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_ptr_args_static_method<P...>(p_func, p_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... P>
|
template <typename... P>
|
||||||
|
@ -1338,105 +1296,134 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) {
|
||||||
return Variant::NIL;
|
return Variant::NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FUNCBINDR(m_func, m_args, m_category) \
|
#define FUNCBINDR(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args, r_error); \
|
call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args, p_argcount, varray(), r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
validated_call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args); \
|
validated_call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
ptr_call_helperr(VariantUtilityFunctions::m_func, ret, p_args); \
|
ptr_call_helperr(VariantUtilityFunctions::m_func, ret, p_args); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static int get_argument_count() { \
|
||||||
return get_arg_count_helperr(VariantUtilityFunctions::m_func); \
|
return get_arg_count_helperr(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return get_arg_type_helperr(VariantUtilityFunctions::m_func, p_arg); \
|
return get_arg_type_helperr(VariantUtilityFunctions::m_func, p_arg); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static Variant::Type get_return_type() { \
|
||||||
return get_ret_type_helperr(VariantUtilityFunctions::m_func); \
|
return get_ret_type_helperr(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool has_return_type() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static bool is_vararg() { return false; } \
|
static bool is_vararg() { return false; } \
|
||||||
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBINDVR(m_func, m_args, m_category) \
|
#define FUNCBINDRD(m_func, m_args, m_defvals, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args, p_argcount, p_defvals, r_error); \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], r_error); \
|
} \
|
||||||
} \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
validated_call_helperr(VariantUtilityFunctions::m_func, r_ret, p_args); \
|
||||||
Callable::CallError ce; \
|
} \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], ce); \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
} \
|
ptr_call_helperr(VariantUtilityFunctions::m_func, ret, p_args); \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
} \
|
||||||
Callable::CallError ce; \
|
static int get_argument_count() { \
|
||||||
PtrToArg<Variant>::encode(VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), ce), ret); \
|
return get_arg_count_helperr(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return 1; \
|
return get_arg_type_helperr(VariantUtilityFunctions::m_func, p_arg); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_return_type() { \
|
||||||
return Variant::NIL; \
|
return get_ret_type_helperr(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static bool has_return_type() { \
|
||||||
return Variant::NIL; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool is_vararg() { return false; } \
|
||||||
return true; \
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
} \
|
}; \
|
||||||
static bool is_vararg() { return false; } \
|
register_utility_function<Func_##m_func>(#m_func, m_args, m_defvals)
|
||||||
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
|
||||||
}; \
|
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
|
||||||
|
|
||||||
#define FUNCBINDVR2(m_func, m_args, m_category) \
|
#define FUNCBINDVR(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], r_error); \
|
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
Callable::CallError ce; \
|
Callable::CallError ce; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], ce); \
|
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], ce); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
Callable::CallError ce; \
|
Callable::CallError ce; \
|
||||||
Variant r; \
|
PtrToArg<Variant>::encode(VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), ce), ret); \
|
||||||
r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), ce); \
|
} \
|
||||||
PtrToArg<Variant>::encode(r, ret); \
|
static int get_argument_count() { \
|
||||||
} \
|
return 1; \
|
||||||
static int get_argument_count() { \
|
} \
|
||||||
return 2; \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
} \
|
return Variant::NIL; \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
} \
|
||||||
return Variant::NIL; \
|
static Variant::Type get_return_type() { \
|
||||||
} \
|
return Variant::NIL; \
|
||||||
static Variant::Type get_return_type() { \
|
} \
|
||||||
return Variant::NIL; \
|
static bool has_return_type() { \
|
||||||
} \
|
return true; \
|
||||||
static bool has_return_type() { \
|
} \
|
||||||
return true; \
|
static bool is_vararg() { return false; } \
|
||||||
} \
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
static bool is_vararg() { return false; } \
|
}; \
|
||||||
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
}; \
|
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
#define FUNCBINDVR2(m_func, m_args, m_category) \
|
||||||
|
class Func_##m_func { \
|
||||||
|
public: \
|
||||||
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
|
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], r_error); \
|
||||||
|
} \
|
||||||
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
|
Callable::CallError ce; \
|
||||||
|
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], ce); \
|
||||||
|
} \
|
||||||
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
|
Callable::CallError ce; \
|
||||||
|
Variant r; \
|
||||||
|
r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), ce); \
|
||||||
|
PtrToArg<Variant>::encode(r, ret); \
|
||||||
|
} \
|
||||||
|
static int get_argument_count() { \
|
||||||
|
return 2; \
|
||||||
|
} \
|
||||||
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
|
return Variant::NIL; \
|
||||||
|
} \
|
||||||
|
static Variant::Type get_return_type() { \
|
||||||
|
return Variant::NIL; \
|
||||||
|
} \
|
||||||
|
static bool has_return_type() { \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
static bool is_vararg() { return false; } \
|
||||||
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
|
}; \
|
||||||
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBINDVR3(m_func, m_args, m_category) \
|
#define FUNCBINDVR3(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], r_error); \
|
*r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], *p_args[2], r_error); \
|
||||||
} \
|
} \
|
||||||
|
@ -1465,175 +1452,176 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) {
|
||||||
static bool is_vararg() { return false; } \
|
static bool is_vararg() { return false; } \
|
||||||
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBINDVARARG(m_func, m_args, m_category) \
|
#define FUNCBINDVARARG(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
Callable::CallError c; \
|
Callable::CallError c; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
Vector<Variant> args; \
|
Vector<Variant> args; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
||||||
} \
|
} \
|
||||||
Vector<const Variant *> argsp; \
|
Vector<const Variant *> argsp; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
argsp.push_back(&args[i]); \
|
argsp.push_back(&args[i]); \
|
||||||
} \
|
} \
|
||||||
Variant r; \
|
Variant r; \
|
||||||
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
||||||
PtrToArg<Variant>::encode(r, ret); \
|
PtrToArg<Variant>::encode(r, ret); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static int get_argument_count() { \
|
||||||
return 2; \
|
return 2; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return Variant::NIL; \
|
return Variant::NIL; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static Variant::Type get_return_type() { \
|
||||||
return Variant::NIL; \
|
return Variant::NIL; \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool has_return_type() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static bool is_vararg() { \
|
static bool is_vararg() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static Variant::UtilityFunctionType get_type() { \
|
static Variant::UtilityFunctionType get_type() { \
|
||||||
return m_category; \
|
return m_category; \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBINDVARARGS(m_func, m_args, m_category) \
|
#define FUNCBINDVARARGS(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
Callable::CallError c; \
|
Callable::CallError c; \
|
||||||
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
*r_ret = VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
Vector<Variant> args; \
|
Vector<Variant> args; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
||||||
} \
|
} \
|
||||||
Vector<const Variant *> argsp; \
|
Vector<const Variant *> argsp; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
argsp.push_back(&args[i]); \
|
argsp.push_back(&args[i]); \
|
||||||
} \
|
} \
|
||||||
Variant r; \
|
Variant r; \
|
||||||
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
||||||
PtrToArg<String>::encode(r.operator String(), ret); \
|
PtrToArg<String>::encode(r.operator String(), ret); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static int get_argument_count() { \
|
||||||
return 1; \
|
return 1; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return Variant::NIL; \
|
return Variant::NIL; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static Variant::Type get_return_type() { \
|
||||||
return Variant::STRING; \
|
return Variant::STRING; \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool has_return_type() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static bool is_vararg() { \
|
static bool is_vararg() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static Variant::UtilityFunctionType get_type() { \
|
static Variant::UtilityFunctionType get_type() { \
|
||||||
return m_category; \
|
return m_category; \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBINDVARARGV(m_func, m_args, m_category) \
|
#define FUNCBINDVARARGV(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
r_error.error = Callable::CallError::CALL_OK; \
|
r_error.error = Callable::CallError::CALL_OK; \
|
||||||
VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
VariantUtilityFunctions::m_func(p_args, p_argcount, r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
Callable::CallError c; \
|
Callable::CallError c; \
|
||||||
VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
VariantUtilityFunctions::m_func(p_args, p_argcount, c); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
Vector<Variant> args; \
|
Vector<Variant> args; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
args.push_back(PtrToArg<Variant>::convert(p_args[i])); \
|
||||||
} \
|
} \
|
||||||
Vector<const Variant *> argsp; \
|
Vector<const Variant *> argsp; \
|
||||||
for (int i = 0; i < p_argcount; i++) { \
|
for (int i = 0; i < p_argcount; i++) { \
|
||||||
argsp.push_back(&args[i]); \
|
argsp.push_back(&args[i]); \
|
||||||
} \
|
} \
|
||||||
Variant r; \
|
Variant r; \
|
||||||
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
validated_call(&r, (const Variant **)argsp.ptr(), p_argcount); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static int get_argument_count() { \
|
||||||
return 1; \
|
return 1; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return Variant::NIL; \
|
return Variant::NIL; \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static Variant::Type get_return_type() { \
|
||||||
return Variant::NIL; \
|
return Variant::NIL; \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool has_return_type() { \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
static bool is_vararg() { \
|
static bool is_vararg() { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
static Variant::UtilityFunctionType get_type() { \
|
static Variant::UtilityFunctionType get_type() { \
|
||||||
return m_category; \
|
return m_category; \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
#define FUNCBIND(m_func, m_args, m_category) \
|
#define FUNCBIND(m_func, m_args, m_category) \
|
||||||
class Func_##m_func { \
|
class Func_##m_func { \
|
||||||
public: \
|
public: \
|
||||||
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
|
static void call(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
|
||||||
call_helper(VariantUtilityFunctions::m_func, p_args, r_error); \
|
call_helper(VariantUtilityFunctions::m_func, p_args, p_argcount, varray(), r_error); \
|
||||||
} \
|
} \
|
||||||
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
|
||||||
validated_call_helper(VariantUtilityFunctions::m_func, p_args); \
|
validated_call_helper(VariantUtilityFunctions::m_func, p_args); \
|
||||||
} \
|
} \
|
||||||
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
|
||||||
ptr_call_helper(VariantUtilityFunctions::m_func, p_args); \
|
ptr_call_helper(VariantUtilityFunctions::m_func, p_args); \
|
||||||
} \
|
} \
|
||||||
static int get_argument_count() { \
|
static int get_argument_count() { \
|
||||||
return get_arg_count_helper(VariantUtilityFunctions::m_func); \
|
return get_arg_count_helper(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_argument_type(int p_arg) { \
|
static Variant::Type get_argument_type(int p_arg) { \
|
||||||
return get_arg_type_helper(VariantUtilityFunctions::m_func, p_arg); \
|
return get_arg_type_helper(VariantUtilityFunctions::m_func, p_arg); \
|
||||||
} \
|
} \
|
||||||
static Variant::Type get_return_type() { \
|
static Variant::Type get_return_type() { \
|
||||||
return get_ret_type_helper(VariantUtilityFunctions::m_func); \
|
return get_ret_type_helper(VariantUtilityFunctions::m_func); \
|
||||||
} \
|
} \
|
||||||
static bool has_return_type() { \
|
static bool has_return_type() { \
|
||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
static bool is_vararg() { return false; } \
|
static bool is_vararg() { return false; } \
|
||||||
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
static Variant::UtilityFunctionType get_type() { return m_category; } \
|
||||||
}; \
|
}; \
|
||||||
register_utility_function<Func_##m_func>(#m_func, m_args)
|
register_utility_function<Func_##m_func>(#m_func, m_args, varray())
|
||||||
|
|
||||||
struct VariantUtilityFunctionInfo {
|
struct VariantUtilityFunctionInfo {
|
||||||
void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = nullptr;
|
void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, const Vector<Variant> &p_defvals, Callable::CallError &r_error) = nullptr;
|
||||||
Variant::ValidatedUtilityFunction validated_call_utility = nullptr;
|
Variant::ValidatedUtilityFunction validated_call_utility = nullptr;
|
||||||
Variant::PTRUtilityFunction ptr_call_utility = nullptr;
|
Variant::PTRUtilityFunction ptr_call_utility = nullptr;
|
||||||
|
Vector<Variant> default_arguments;
|
||||||
Vector<String> argnames;
|
Vector<String> argnames;
|
||||||
bool is_vararg = false;
|
bool is_vararg = false;
|
||||||
bool returns_value = false;
|
bool returns_value = false;
|
||||||
|
@ -1647,7 +1635,7 @@ static OAHashMap<StringName, VariantUtilityFunctionInfo> utility_function_table;
|
||||||
static List<StringName> utility_function_name_table;
|
static List<StringName> utility_function_name_table;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void register_utility_function(const String &p_name, const Vector<String> &argnames) {
|
static void register_utility_function(const String &p_name, const Vector<String> &argnames, const Vector<Variant> &p_def_args) {
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
if (name.begins_with("_")) {
|
if (name.begins_with("_")) {
|
||||||
name = name.substr(1, name.length() - 1);
|
name = name.substr(1, name.length() - 1);
|
||||||
|
@ -1660,6 +1648,7 @@ static void register_utility_function(const String &p_name, const Vector<String>
|
||||||
bfi.validated_call_utility = T::validated_call;
|
bfi.validated_call_utility = T::validated_call;
|
||||||
bfi.ptr_call_utility = T::ptrcall;
|
bfi.ptr_call_utility = T::ptrcall;
|
||||||
bfi.is_vararg = T::is_vararg();
|
bfi.is_vararg = T::is_vararg();
|
||||||
|
bfi.default_arguments = p_def_args;
|
||||||
bfi.argnames = argnames;
|
bfi.argnames = argnames;
|
||||||
bfi.argcount = T::get_argument_count();
|
bfi.argcount = T::get_argument_count();
|
||||||
if (!bfi.is_vararg) {
|
if (!bfi.is_vararg) {
|
||||||
|
@ -1786,7 +1775,7 @@ void Variant::_register_variant_utility_functions() {
|
||||||
FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBINDR(randf, sarray(), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
FUNCBINDR(randi_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBINDR(randi_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
FUNCBINDR(randf_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBINDR(randf_range, sarray("from", "to"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
FUNCBINDR(randfn, sarray("mean", "deviation"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBINDRD(randfn, sarray("mean", "deviation"), varray(0.0, 1.0), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
FUNCBIND(seed, sarray("base"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBIND(seed, sarray("base"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
FUNCBINDR(rand_from_seed, sarray("seed"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
FUNCBINDR(rand_from_seed, sarray("seed"), Variant::UTILITY_FUNC_TYPE_RANDOM);
|
||||||
|
|
||||||
|
@ -1843,9 +1832,9 @@ void Variant::call_utility_function(const StringName &p_name, Variant *r_ret, co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!bfi->is_vararg && p_argcount < bfi->argcount)) {
|
if (unlikely(!bfi->is_vararg && p_argcount < bfi->argcount - bfi->default_arguments.size())) {
|
||||||
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
r_error.expected = bfi->argcount;
|
r_error.expected = bfi->argcount - bfi->default_arguments.size();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1855,7 +1844,7 @@ void Variant::call_utility_function(const StringName &p_name, Variant *r_ret, co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bfi->call_utility(r_ret, p_args, p_argcount, r_error);
|
bfi->call_utility(r_ret, p_args, p_argcount, bfi->default_arguments, r_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::has_utility_function(const StringName &p_name) {
|
bool Variant::has_utility_function(const StringName &p_name) {
|
||||||
|
@ -1907,6 +1896,7 @@ MethodInfo Variant::get_utility_function_info(const StringName &p_name) {
|
||||||
arg.name = bfi->argnames[i];
|
arg.name = bfi->argnames[i];
|
||||||
info.arguments.push_back(arg);
|
info.arguments.push_back(arg);
|
||||||
}
|
}
|
||||||
|
info.default_arguments = bfi->default_arguments;
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -1920,6 +1910,24 @@ int Variant::get_utility_function_argument_count(const StringName &p_name) {
|
||||||
return bfi->argcount;
|
return bfi->argcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<Variant> Variant::get_utility_function_default_arguments(const StringName &p_name) {
|
||||||
|
const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
|
||||||
|
if (!bfi) {
|
||||||
|
return varray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bfi->default_arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Variant::get_utility_function_default_argument_index(const StringName &p_name, int p_arg) {
|
||||||
|
const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
|
||||||
|
if (!bfi) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_arg - (bfi->argcount - bfi->default_arguments.size());
|
||||||
|
}
|
||||||
|
|
||||||
Variant::Type Variant::get_utility_function_argument_type(const StringName &p_name, int p_arg) {
|
Variant::Type Variant::get_utility_function_argument_type(const StringName &p_name, int p_arg) {
|
||||||
const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
|
const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
|
||||||
if (!bfi) {
|
if (!bfi) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ struct VariantUtilityFunctions {
|
||||||
static void randomize();
|
static void randomize();
|
||||||
static int64_t randi();
|
static int64_t randi();
|
||||||
static double randf();
|
static double randf();
|
||||||
static double randfn(double mean, double deviation);
|
static double randfn(double mean = 0.0, double deviation = 1.0);
|
||||||
static int64_t randi_range(int64_t from, int64_t to);
|
static int64_t randi_range(int64_t from, int64_t to);
|
||||||
static double randf_range(double from, double to);
|
static double randf_range(double from, double to);
|
||||||
static void seed(int64_t s);
|
static void seed(int64_t s);
|
||||||
|
|
|
@ -1033,8 +1033,8 @@
|
||||||
</method>
|
</method>
|
||||||
<method name="randfn">
|
<method name="randfn">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<param index="0" name="mean" type="float" />
|
<param index="0" name="mean" type="float" default="0.0" />
|
||||||
<param index="1" name="deviation" type="float" />
|
<param index="1" name="deviation" type="float" default="1.0" />
|
||||||
<description>
|
<description>
|
||||||
Returns a [url=https://en.wikipedia.org/wiki/Normal_distribution]normally-distributed[/url], pseudo-random floating-point value from the specified [param mean] and a standard [param deviation]. This is also known as a Gaussian distribution.
|
Returns a [url=https://en.wikipedia.org/wiki/Normal_distribution]normally-distributed[/url], pseudo-random floating-point value from the specified [param mean] and a standard [param deviation]. This is also known as a Gaussian distribution.
|
||||||
[b]Note:[/b] This method uses the [url=https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform]Box-Muller transform[/url] algorithm.
|
[b]Note:[/b] This method uses the [url=https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform]Box-Muller transform[/url] algorithm.
|
||||||
|
|
|
@ -981,6 +981,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
|
||||||
if (Variant::is_utility_function_vararg(E)) {
|
if (Variant::is_utility_function_vararg(E)) {
|
||||||
md.qualifiers = "vararg";
|
md.qualifiers = "vararg";
|
||||||
} else {
|
} else {
|
||||||
|
const Vector<Variant> def_args = Variant::get_utility_function_default_arguments(E);
|
||||||
for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) {
|
for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) {
|
||||||
PropertyInfo pi;
|
PropertyInfo pi;
|
||||||
pi.type = Variant::get_utility_function_argument_type(E, i);
|
pi.type = Variant::get_utility_function_argument_type(E, i);
|
||||||
|
@ -990,6 +991,12 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
|
||||||
}
|
}
|
||||||
DocData::ArgumentDoc ad;
|
DocData::ArgumentDoc ad;
|
||||||
DocData::argument_doc_from_arginfo(ad, pi);
|
DocData::argument_doc_from_arginfo(ad, pi);
|
||||||
|
|
||||||
|
const int dargidx = Variant::get_utility_function_default_argument_index(E, i);
|
||||||
|
if (dargidx >= 0) {
|
||||||
|
ad.default_value = DocData::get_default_value_string(def_args[dargidx]);
|
||||||
|
}
|
||||||
|
|
||||||
md.arguments.push_back(ad);
|
md.arguments.push_back(ad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ static MethodInfo info_from_utility_func(const StringName &p_function) {
|
||||||
pi.type = Variant::get_utility_function_argument_type(p_function, i);
|
pi.type = Variant::get_utility_function_argument_type(p_function, i);
|
||||||
info.arguments.push_back(pi);
|
info.arguments.push_back(pi);
|
||||||
}
|
}
|
||||||
|
info.default_arguments = Variant::get_utility_function_default_arguments(p_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -621,6 +621,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
||||||
if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(call->function_name) < Variant::VARIANT_MAX) {
|
if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(call->function_name) < Variant::VARIANT_MAX) {
|
||||||
gen->write_construct(result, GDScriptParser::get_builtin_type(call->function_name), arguments);
|
gen->write_construct(result, GDScriptParser::get_builtin_type(call->function_name), arguments);
|
||||||
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && Variant::has_utility_function(call->function_name)) {
|
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && Variant::has_utility_function(call->function_name)) {
|
||||||
|
int arg_count = Variant::get_utility_function_argument_count(call->function_name);
|
||||||
|
|
||||||
|
if (call->arguments.size() < arg_count) {
|
||||||
|
Vector<Variant> def_args = Variant::get_utility_function_default_arguments(call->function_name);
|
||||||
|
|
||||||
|
for (int i = call->arguments.size(); i < arg_count; i++) {
|
||||||
|
const int dargidx = Variant::get_utility_function_default_argument_index(call->function_name, i);
|
||||||
|
|
||||||
|
if (dargidx >= 0) {
|
||||||
|
arguments.push_back(codegen.add_constant(def_args[dargidx]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Variant utility function.
|
// Variant utility function.
|
||||||
gen->write_call_utility(result, call->function_name, arguments);
|
gen->write_call_utility(result, call->function_name, arguments);
|
||||||
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) {
|
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) {
|
||||||
|
|
|
@ -2167,12 +2167,19 @@ TEST_CASE("[Variant] Utility functions") {
|
||||||
if (Variant::is_utility_function_vararg(E)) {
|
if (Variant::is_utility_function_vararg(E)) {
|
||||||
md.is_vararg = true;
|
md.is_vararg = true;
|
||||||
} else {
|
} else {
|
||||||
|
const Vector<Variant> def_args = Variant::get_utility_function_default_arguments(E);
|
||||||
for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) {
|
for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) {
|
||||||
ArgumentData arg;
|
ArgumentData arg;
|
||||||
arg.type = Variant::get_utility_function_argument_type(E, i);
|
arg.type = Variant::get_utility_function_argument_type(E, i);
|
||||||
arg.name = Variant::get_utility_function_argument_name(E, i);
|
arg.name = Variant::get_utility_function_argument_name(E, i);
|
||||||
arg.position = i;
|
arg.position = i;
|
||||||
|
|
||||||
|
const int dargidx = Variant::get_utility_function_default_argument_index(E, i);
|
||||||
|
if (dargidx >= 0) {
|
||||||
|
arg.has_defval = true;
|
||||||
|
arg.defval = def_args[dargidx];
|
||||||
|
}
|
||||||
|
|
||||||
md.arguments.push_back(arg);
|
md.arguments.push_back(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2187,6 +2194,13 @@ TEST_CASE("[Variant] Utility functions") {
|
||||||
|
|
||||||
TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")),
|
TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")),
|
||||||
vformat("Unnamed argument in position %d of function '%s'.", arg.position, E.name));
|
vformat("Unnamed argument in position %d of function '%s'.", arg.position, E.name));
|
||||||
|
|
||||||
|
if (arg.has_defval) {
|
||||||
|
const bool arg_defval_assignable_to_type = arg.type == arg.defval.get_type();
|
||||||
|
|
||||||
|
TEST_COND(!arg_defval_assignable_to_type,
|
||||||
|
vformat("Invalid default value for parameter '%s' of function '%s'.", arg.name, E.name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue