diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index d7800dc942..40c5f499c1 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -35,113 +35,215 @@ #include "core/typedefs.h" #include "core/variant/variant.h" +namespace Internal { + +template +struct PtrToArgDirect { + _FORCE_INLINE_ static const T &convert(const void *p_ptr) { + return *reinterpret_cast(p_ptr); + } + typedef T EncodeT; + _FORCE_INLINE_ static void encode(T p_val, void *p_ptr) { + *((T *)p_ptr) = p_val; + } +}; + +template +struct PtrToArgConvert { + _FORCE_INLINE_ static T convert(const void *p_ptr) { + return static_cast(*reinterpret_cast(p_ptr)); + } + typedef S EncodeT; + _FORCE_INLINE_ static void encode(T p_val, void *p_ptr) { + *((S *)p_ptr) = static_cast(p_val); + } +}; + +template +struct PtrToArgByReference { + _FORCE_INLINE_ static const T &convert(const void *p_ptr) { + return *reinterpret_cast(p_ptr); + } + typedef T EncodeT; + _FORCE_INLINE_ static void encode(const T &p_val, void *p_ptr) { + *((T *)p_ptr) = p_val; + } +}; + +template +struct PtrToArgVectorConvert { + _FORCE_INLINE_ static Vector convert(const void *p_ptr) { + const Vector *dvs = reinterpret_cast *>(p_ptr); + Vector ret; + int len = dvs->size(); + ret.resize(len); + { + const T *r = dvs->ptr(); + for (int i = 0; i < len; i++) { + ret.write[i] = r[i]; + } + } + return ret; + } + // No EncodeT because direct pointer conversion not possible. + _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { + Vector *dv = reinterpret_cast *>(p_ptr); + int len = p_vec.size(); + dv->resize(len); + { + T *w = dv->ptrw(); + for (int i = 0; i < len; i++) { + w[i] = p_vec[i]; + } + } + } +}; + +template +struct PtrToArgVectorFromArray { + _FORCE_INLINE_ static Vector convert(const void *p_ptr) { + const Array *arr = reinterpret_cast(p_ptr); + Vector ret; + int len = arr->size(); + ret.resize(len); + for (int i = 0; i < len; i++) { + ret.write[i] = (*arr)[i]; + } + return ret; + } + // No EncodeT because direct pointer conversion not possible. + _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { + Array *arr = reinterpret_cast(p_ptr); + int len = p_vec.size(); + arr->resize(len); + for (int i = 0; i < len; i++) { + (*arr)[i] = p_vec[i]; + } + } +}; + +template +struct PtrToArgStringConvertByReference { + _FORCE_INLINE_ static T convert(const void *p_ptr) { + T s = *reinterpret_cast(p_ptr); + return s; + } + // No EncodeT because direct pointer conversion not possible. + _FORCE_INLINE_ static void encode(const T &p_vec, void *p_ptr) { + String *arr = reinterpret_cast(p_ptr); + *arr = p_vec; + } +}; + +} //namespace Internal + template struct PtrToArg; template struct PtrToArg>>> : PtrToArg> {}; -#define MAKE_PTRARG(m_type) \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \ - return *reinterpret_cast(p_ptr); \ - } \ - typedef m_type EncodeT; \ - _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ - *((m_type *)p_ptr) = p_val; \ - } \ - }; - -#define MAKE_PTRARGCONV(m_type, m_conv) \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ - return static_cast(*reinterpret_cast(p_ptr)); \ - } \ - typedef m_conv EncodeT; \ - _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ - *((m_conv *)p_ptr) = static_cast(p_val); \ - } \ - }; - -#define MAKE_PTRARG_BY_REFERENCE(m_type) \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \ - return *reinterpret_cast(p_ptr); \ - } \ - typedef m_type EncodeT; \ - _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ - *((m_type *)p_ptr) = p_val; \ - } \ - }; - -#define MAKE_PTRARGCONV_CONDITIONAL(m_type, m_conv, m_conditional) \ - template \ - struct PtrToArg> { \ - _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ - return static_cast(*reinterpret_cast(p_ptr)); \ - } \ - typedef m_conv EncodeT; \ - _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ - *((m_conv *)p_ptr) = static_cast(p_val); \ - } \ - }; - -MAKE_PTRARGCONV(bool, uint8_t); +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; // Integer types. -MAKE_PTRARGCONV(uint8_t, int64_t); -MAKE_PTRARGCONV(int8_t, int64_t); -MAKE_PTRARGCONV(uint16_t, int64_t); -MAKE_PTRARGCONV(int16_t, int64_t); -MAKE_PTRARGCONV(uint32_t, int64_t); -MAKE_PTRARGCONV(int32_t, int64_t); -MAKE_PTRARG(int64_t); -MAKE_PTRARG(uint64_t); +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; // Float types -MAKE_PTRARGCONV(float, double); -MAKE_PTRARG(double); +template <> +struct PtrToArg : Internal::PtrToArgConvert {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; -MAKE_PTRARG(String); -MAKE_PTRARG(Vector2); -MAKE_PTRARG(Vector2i); -MAKE_PTRARG(Rect2); -MAKE_PTRARG(Rect2i); -MAKE_PTRARG_BY_REFERENCE(Vector3); -MAKE_PTRARG_BY_REFERENCE(Vector3i); -MAKE_PTRARG_BY_REFERENCE(Vector4); -MAKE_PTRARG_BY_REFERENCE(Vector4i); -MAKE_PTRARG(Transform2D); -MAKE_PTRARG(Projection); -MAKE_PTRARG_BY_REFERENCE(Plane); -MAKE_PTRARG(Quaternion); -MAKE_PTRARG_BY_REFERENCE(AABB); -MAKE_PTRARG_BY_REFERENCE(Basis); -MAKE_PTRARG_BY_REFERENCE(Transform3D); -MAKE_PTRARG_BY_REFERENCE(Color); -MAKE_PTRARG(StringName); -MAKE_PTRARG(NodePath); -MAKE_PTRARG(RID); +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; // Object doesn't need this. -MAKE_PTRARG(Callable); -MAKE_PTRARG(Signal); -MAKE_PTRARG(Dictionary); -MAKE_PTRARG(Array); -MAKE_PTRARG(PackedByteArray); -MAKE_PTRARG(PackedInt32Array); -MAKE_PTRARG(PackedInt64Array); -MAKE_PTRARG(PackedFloat32Array); -MAKE_PTRARG(PackedFloat64Array); -MAKE_PTRARG(PackedStringArray); -MAKE_PTRARG(PackedVector2Array); -MAKE_PTRARG(PackedVector3Array); -MAKE_PTRARG(PackedColorArray); -MAKE_PTRARG(PackedVector4Array); -MAKE_PTRARG_BY_REFERENCE(Variant); +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgDirect {}; +template <> +struct PtrToArg : Internal::PtrToArgByReference {}; -MAKE_PTRARGCONV_CONDITIONAL(T, int64_t, std::is_enum_v); -MAKE_PTRARGCONV_CONDITIONAL(BitField, int64_t, std::is_enum_v); +template +struct PtrToArg>> : Internal::PtrToArgConvert {}; +template +struct PtrToArg, std::enable_if_t>> : Internal::PtrToArgConvert, int64_t> {}; // This is for Object. @@ -182,147 +284,23 @@ struct PtrToArg { // This is for the special cases used by Variant. -// No EncodeT because direct pointer conversion not possible. -#define MAKE_VECARG(m_type) \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Vector *dvs = reinterpret_cast *>(p_ptr); \ - Vector ret; \ - int len = dvs->size(); \ - ret.resize(len); \ - { \ - const m_type *r = dvs->ptr(); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = r[i]; \ - } \ - } \ - return ret; \ - } \ - _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { \ - Vector *dv = reinterpret_cast *>(p_ptr); \ - int len = p_vec.size(); \ - dv->resize(len); \ - { \ - m_type *w = dv->ptrw(); \ - for (int i = 0; i < len; i++) { \ - w[i] = p_vec[i]; \ - } \ - } \ - } \ - }; - -// No EncodeT because direct pointer conversion not possible. -#define MAKE_VECARG_ALT(m_type, m_type_alt) \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Vector *dvs = reinterpret_cast *>(p_ptr); \ - Vector ret; \ - int len = dvs->size(); \ - ret.resize(len); \ - { \ - const m_type *r = dvs->ptr(); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = r[i]; \ - } \ - } \ - return ret; \ - } \ - _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { \ - Vector *dv = reinterpret_cast *>(p_ptr); \ - int len = p_vec.size(); \ - dv->resize(len); \ - { \ - m_type *w = dv->ptrw(); \ - for (int i = 0; i < len; i++) { \ - w[i] = p_vec[i]; \ - } \ - } \ - } \ - }; - -MAKE_VECARG_ALT(String, StringName); +template <> +struct PtrToArg> : Internal::PtrToArgVectorConvert {}; // For stuff that gets converted to Array vectors. -// No EncodeT because direct pointer conversion not possible. -#define MAKE_VECARR(m_type) \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Array *arr = reinterpret_cast(p_ptr); \ - Vector ret; \ - int len = arr->size(); \ - ret.resize(len); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = (*arr)[i]; \ - } \ - return ret; \ - } \ - _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { \ - Array *arr = reinterpret_cast(p_ptr); \ - int len = p_vec.size(); \ - arr->resize(len); \ - for (int i = 0; i < len; i++) { \ - (*arr)[i] = p_vec[i]; \ - } \ - } \ - }; - -MAKE_VECARR(Variant); -MAKE_VECARR(RID); -MAKE_VECARR(Plane); - -// No EncodeT because direct pointer conversion not possible. -#define MAKE_DVECARR(m_type) \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Array *arr = reinterpret_cast(p_ptr); \ - Vector ret; \ - int len = arr->size(); \ - ret.resize(len); \ - { \ - m_type *w = ret.ptrw(); \ - for (int i = 0; i < len; i++) { \ - w[i] = (*arr)[i]; \ - } \ - } \ - return ret; \ - } \ - _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { \ - Array *arr = reinterpret_cast(p_ptr); \ - int len = p_vec.size(); \ - arr->resize(len); \ - { \ - const m_type *r = p_vec.ptr(); \ - for (int i = 0; i < len; i++) { \ - (*arr)[i] = r[i]; \ - } \ - } \ - } \ - }; +template <> +struct PtrToArg> : Internal::PtrToArgVectorFromArray {}; +template <> +struct PtrToArg> : Internal::PtrToArgVectorFromArray {}; +template <> +struct PtrToArg> : Internal::PtrToArgVectorFromArray {}; // Special case for IPAddress. -// No EncodeT because direct pointer conversion not possible. -#define MAKE_STRINGCONV_BY_REFERENCE(m_type) \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ - m_type s = *reinterpret_cast(p_ptr); \ - return s; \ - } \ - _FORCE_INLINE_ static void encode(const m_type &p_vec, void *p_ptr) { \ - String *arr = reinterpret_cast(p_ptr); \ - *arr = p_vec; \ - } \ - }; +template <> +struct PtrToArg : Internal::PtrToArgStringConvertByReference {}; -MAKE_STRINGCONV_BY_REFERENCE(IPAddress); - -// No EncodeT because direct pointer conversion not possible. template <> struct PtrToArg> { _FORCE_INLINE_ static Vector convert(const void *p_ptr) { @@ -341,6 +319,7 @@ struct PtrToArg> { } return ret; } + // No EncodeT because direct pointer conversion not possible. _FORCE_INLINE_ static void encode(const Vector &p_vec, void *p_ptr) { Vector *arr = reinterpret_cast *>(p_ptr); int len = p_vec.size();