diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/project_settings.cpp | 2 | ||||
-rw-r--r-- | core/core_constants.cpp | 1 | ||||
-rw-r--r-- | core/debugger/remote_debugger_peer.cpp | 7 | ||||
-rw-r--r-- | core/io/file_access_compressed.cpp | 2 | ||||
-rw-r--r-- | core/io/file_access_encrypted.cpp | 2 | ||||
-rw-r--r-- | core/io/file_access_memory.cpp | 2 | ||||
-rw-r--r-- | core/io/file_access_network.cpp | 2 | ||||
-rw-r--r-- | core/io/file_access_pack.cpp | 2 | ||||
-rw-r--r-- | core/io/file_access_zip.cpp | 2 | ||||
-rw-r--r-- | core/object/method_bind.h | 1 | ||||
-rw-r--r-- | core/os/file_access.cpp | 2 | ||||
-rw-r--r-- | core/variant/binder_common.h | 164 | ||||
-rw-r--r-- | core/variant/variant.h | 3 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 157 |
14 files changed, 338 insertions, 11 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index f7a6a8ece0..f87dc6704e 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -643,7 +643,6 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, } else if (err != ERR_FILE_NOT_FOUND) { // If the file exists but can't be loaded, we want to know it. ERR_PRINT("Couldn't load file '" + p_bin_path + "', error code " + itos(err) + "."); - return err; } // Fallback to text-based project.godot file if binary was not found. @@ -652,7 +651,6 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, return OK; } else if (err != ERR_FILE_NOT_FOUND) { ERR_PRINT("Couldn't load file '" + p_text_path + "', error code " + itos(err) + "."); - return err; } return err; diff --git a/core/core_constants.cpp b/core/core_constants.cpp index a99df93638..5abfee05bf 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -564,6 +564,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_REVERSE); BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL); BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT); + BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC); BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 857e3af268..90b0975159 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -190,13 +190,18 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po } void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) { + const uint64_t min_tick = 100; RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud; while (peer->running && peer->is_peer_connected()) { + uint64_t ticks_usec = OS::get_singleton()->get_ticks_usec(); peer->_poll(); if (!peer->is_peer_connected()) { break; } - peer->tcp_client->poll(NetSocket::POLL_TYPE_IN_OUT, 1); + ticks_usec = OS::get_singleton()->get_ticks_usec() - ticks_usec; + if (ticks_usec < min_tick) { + OS::get_singleton()->delay_usec(min_tick - ticks_usec); + } } } diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index ade4b2c1ac..b2440629e3 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -286,7 +286,7 @@ uint8_t FileAccessCompressed::get_8() const { } int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use."); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 133ec18762..8ace897f18 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -237,7 +237,7 @@ uint8_t FileAccessEncrypted::get_8() const { } int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 4bab8c1d3d..58670d5246 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -138,7 +138,7 @@ uint8_t FileAccessMemory::get_8() const { } int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!data, -1); diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index e09c3552ef..31b7d658d0 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -366,7 +366,7 @@ void FileAccessNetwork::_queue_page(int p_page) const { } int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); //bool eof=false; diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 17d54e5cb6..e24dc40166 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -299,7 +299,7 @@ uint8_t FileAccessPack::get_8() const { } int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); if (eof) { diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 5364125abb..586c988974 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -303,7 +303,7 @@ uint8_t FileAccessZip::get_8() const { } int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); ERR_FAIL_COND_V(!zfile, -1); at_eof = unzeof(zfile); diff --git a/core/object/method_bind.h b/core/object/method_bind.h index 7cf4f8d4e8..7030ae201b 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -42,6 +42,7 @@ enum MethodFlags { METHOD_FLAG_VIRTUAL = 32, METHOD_FLAG_FROM_SCRIPT = 64, METHOD_FLAG_VARARG = 128, + METHOD_FLAG_STATIC = 256, METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL, }; diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index e3a84732dc..ad234c2d49 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -368,7 +368,7 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const { } int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const { - ERR_FAIL_COND_V(!p_dst, -1); + ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V(p_length < 0, -1); int i = 0; for (i = 0; i < p_length && !eof_reached(); i++) { diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 490bd45b7b..8c0b7907e3 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -238,6 +238,16 @@ void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P.. PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret); } +template <class R, class... P, size_t... Is> +void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) { + PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret); +} + +template <class... P, size_t... Is> +void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) { + p_method(PtrToArg<P>::convert(p_args[Is])...); +} + 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]))...); @@ -263,6 +273,16 @@ void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_me 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 R, class... P, size_t... Is> +void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) { + VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...)); +} + +template <class... P, size_t... Is> +void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) { + p_method((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 @@ -456,6 +476,16 @@ void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), con call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); } +template <class R, class... P> +void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) { + call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + 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)>{}); @@ -476,6 +506,16 @@ void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T 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)>{}); } +template <class... P> +void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) { + call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class R, class... P> +void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method_ret_helper<R, P...>(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__) @@ -566,6 +606,28 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co #endif } +template <class R, class... P, size_t... Is> +void call_with_variant_args_static_ret(R (*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_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif +} + +template <class... P, size_t... Is> +void call_with_variant_args_static(void (*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_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + (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 @@ -596,6 +658,42 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co (void)p_args; } +template <class R, class... P> +void call_with_variant_args_static_ret(R (*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_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_variant_args_static_ret(void (*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_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + 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 @@ -660,6 +758,72 @@ void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); } +template <class R, class... P> +void call_with_variant_args_static_ret_dv(R (*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_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class... P> +void call_with_variant_args_static_dv(void (*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_static(p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + #if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/core/variant/variant.h b/core/variant/variant.h index 5050aa24ec..0acafc64fa 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -495,6 +495,7 @@ public: static bool has_builtin_method_return_value(Variant::Type p_type, const StringName &p_method); static Variant::Type get_builtin_method_return_type(Variant::Type p_type, const StringName &p_method); static bool is_builtin_method_const(Variant::Type p_type, const StringName &p_method); + static bool is_builtin_method_static(Variant::Type p_type, const StringName &p_method); static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method); static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list); static int get_builtin_method_count(Variant::Type p_type); @@ -502,6 +503,8 @@ public: void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()); + static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); + static String get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 90272ad5b4..8c1d8066d6 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -42,6 +42,16 @@ typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); +template <class R, class... P> +static _FORCE_INLINE_ void vc_static_method_call(R (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_ret_dv(method, p_args, p_argcount, r_ret, r_error, p_defvals); +} + +template <class... P> +static _FORCE_INLINE_ void vc_static_method_call(void (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { + call_with_variant_args_static_dv(method, p_args, p_argcount, r_error, p_defvals); +} + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals); @@ -81,6 +91,16 @@ static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Vari call_with_validated_variant_argsc(base, method, p_args); } +template <class R, class... P> +static _FORCE_INLINE_ void vc_validated_static_call(R (*method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method_ret(method, p_args, r_ret); +} + +template <class... P> +static _FORCE_INLINE_ void vc_validated_static_call(void (*method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_method(method, p_args); +} + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) { call_with_ptr_args_ret(reinterpret_cast<T *>(p_base), method, p_args, r_ret); @@ -150,6 +170,11 @@ static _FORCE_INLINE_ int vc_get_argument_count(R (*method)(T *, P...)) { return sizeof...(P); } +template <class R, class... P> +static _FORCE_INLINE_ int vc_get_argument_count_static(R (*method)(P...)) { + return sizeof...(P); +} + template <class R, class T, class... P> static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...), int p_arg) { return call_get_argument_type<P...>(p_arg); @@ -174,6 +199,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (*method)(T *, P...), return call_get_argument_type<P...>(p_arg); } +template <class R, class... P> +static _FORCE_INLINE_ Variant::Type vc_get_argument_type_static(R (*method)(P...), int p_arg) { + return call_get_argument_type<P...>(p_arg); +} + template <class R, class T, class... P> static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...)) { return GetTypeInfo<R>::VARIANT_TYPE; @@ -218,6 +248,16 @@ static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...) const) { return false; } +template <class... P> +static _FORCE_INLINE_ bool vc_has_return_type_static(void (*method)(P...)) { + return false; +} + +template <class R, class... P> +static _FORCE_INLINE_ bool vc_has_return_type_static(R (*method)(P...)) { + return true; +} + template <class R, class T, class... P> static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...)) { return false; @@ -283,6 +323,9 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con static bool is_const() { \ return vc_is_const(m_method_ptr); \ } \ + static bool is_static() { \ + return false; \ + } \ static bool is_vararg() { \ return false; \ } \ @@ -294,6 +337,57 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con } \ }; +template <class R, class... P> +static _FORCE_INLINE_ void vc_static_ptrcall(R (*method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method_ret<R, P...>(method, p_args, r_ret); +} + +template <class... P> +static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void **p_args, void *r_ret) { + call_with_ptr_args_static_method<P...>(method, p_args); +} + +#define STATIC_METHOD_CLASS(m_class, m_method_name, m_method_ptr) \ + struct Method_##m_class##_##m_method_name { \ + static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \ + vc_static_method_call(m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \ + } \ + static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \ + vc_change_return_type(m_method_ptr, r_ret); \ + vc_validated_static_call(m_method_ptr, p_args, r_ret); \ + } \ + static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \ + vc_static_ptrcall(m_method_ptr, p_args, r_ret); \ + } \ + static int get_argument_count() { \ + return vc_get_argument_count_static(m_method_ptr); \ + } \ + static Variant::Type get_argument_type(int p_arg) { \ + return vc_get_argument_type_static(m_method_ptr, p_arg); \ + } \ + static Variant::Type get_return_type() { \ + return vc_get_return_type(m_method_ptr); \ + } \ + static bool has_return_type() { \ + return vc_has_return_type_static(m_method_ptr); \ + } \ + static bool is_const() { \ + return false; \ + } \ + static bool is_static() { \ + return true; \ + } \ + static bool is_vararg() { \ + return false; \ + } \ + static Variant::Type get_base_type() { \ + return GetTypeInfo<m_class>::VARIANT_TYPE; \ + } \ + static StringName get_name() { \ + return #m_method_name; \ + } \ + }; + template <class R, class T, class... P> static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) { call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret); @@ -326,6 +420,9 @@ static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, cons static bool is_const() { \ return true; \ } \ + static bool is_static() { \ + return false; \ + } \ static bool is_vararg() { \ return false; \ } \ @@ -379,6 +476,9 @@ static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, cons static bool is_const() { \ return true; \ } \ + static bool is_static() { \ + return false; \ + } \ static bool is_vararg() { \ return true; \ } \ @@ -549,6 +649,7 @@ struct VariantBuiltInMethodInfo { Vector<String> argument_names; bool is_const; + bool is_static; bool has_return_type; bool is_vararg; Variant::Type return_type; @@ -580,6 +681,7 @@ static void register_builtin_method(const Vector<String> &p_argnames, const Vect imi.argument_names = p_argnames; imi.is_const = T::is_const(); + imi.is_static = T::is_static(); imi.is_vararg = T::is_vararg(); imi.has_return_type = T::has_return_type(); imi.return_type = T::get_return_type(); @@ -625,6 +727,24 @@ void Variant::call(const StringName &p_method, const Variant **p_args, int p_arg } } +void Variant::call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + + const VariantBuiltInMethodInfo *imf = builtin_method_info[p_type].lookup_ptr(p_method); + + if (!imf) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + return; + } + + if (!imf->is_static) { + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; + return; + } + + imf->call(nullptr, p_args, p_argcount, r_ret, imf->default_arguments, r_error); +} + bool Variant::has_method(const StringName &p_method) const { if (type == OBJECT) { Object *obj = get_validated_object(); @@ -724,6 +844,13 @@ bool Variant::is_builtin_method_const(Variant::Type p_type, const StringName &p_ return method->is_const; } +bool Variant::is_builtin_method_static(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, false); + return method->is_static; +} + bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); @@ -759,7 +886,9 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { if (method->is_vararg) { mi.flags |= METHOD_FLAG_VARARG; } - + if (method->is_static) { + mi.flags |= METHOD_FLAG_STATIC; + } for (int i = 0; i < method->argument_count; i++) { PropertyInfo pi; #ifdef DEBUG_METHODS_ENABLED @@ -855,6 +984,16 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va #endif #ifdef DEBUG_METHODS_ENABLED +#define bind_static_method(m_type, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_method, m_type::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(m_arg_names, m_default_args); +#else +#define bind_static_method(m_type, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_method, m_type ::m_method); \ + register_builtin_method<Method_##m_type##_##m_method>(sarray(), m_default_args); +#endif + +#ifdef DEBUG_METHODS_ENABLED #define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ METHOD_CLASS(m_type, m_name, m_method); \ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args); @@ -983,6 +1122,11 @@ static void _register_variant_builtin_methods() { bind_method(String, to_utf16_buffer, sarray(), varray()); bind_method(String, to_utf32_buffer, sarray(), varray()); + bind_static_method(String, num_scientific, sarray("number"), varray()); + bind_static_method(String, num, sarray("number", "decimals"), varray(-1)); + bind_static_method(String, chr, sarray("char"), varray()); + bind_static_method(String, humanize_size, sarray("size"), varray()); + /* Vector2 */ bind_method(Vector2, angle, sarray(), varray()); @@ -1147,6 +1291,17 @@ static void _register_variant_builtin_methods() { //ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0)); bind_method(Color, is_equal_approx, sarray("to"), varray()); + bind_static_method(Color, hex, sarray("hex"), varray()); + bind_static_method(Color, hex64, sarray("hex"), varray()); + bind_static_method(Color, html, sarray("rgba"), varray()); + bind_static_method(Color, html_is_valid, sarray("color"), varray()); + bind_static_method(Color, find_named_color, sarray("name"), varray()); + bind_static_method(Color, get_named_color_count, sarray(), varray()); + bind_static_method(Color, get_named_color_name, sarray("idx"), varray()); + bind_static_method(Color, get_named_color, sarray("idx"), varray()); + bind_static_method(Color, from_string, sarray("str", "default"), varray()); + bind_static_method(Color, from_rgbe9995, sarray("rgbe"), varray()); + /* RID */ bind_method(RID, get_id, sarray(), varray()); |