diff --git a/core/core_bind.cpp b/core/core_bind.cpp index a13168beed7..8fa7aad0acf 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -982,10 +982,11 @@ Vector Geometry3D::segment_intersects_cylinder(const Vector3 &p_from, c return r; } -Vector Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_planes) { +Vector Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray &p_planes) { Vector r; Vector3 res, norm; - if (!::Geometry3D::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) { + Vector planes = Variant(p_planes); + if (!::Geometry3D::segment_intersects_convex(p_from, p_to, planes.ptr(), planes.size(), &res, &norm)) { return r; } diff --git a/core/core_bind.h b/core/core_bind.h index e34f8f3f5b9..be43ae2c9d2 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -326,7 +326,7 @@ public: Vector segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius); Vector segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius); - Vector segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector &p_planes); + Vector segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray &p_planes); Vector clip_polygon(const Vector &p_points, const Plane &p_plane); diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index f158755a856..91038b9bdf8 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -146,9 +146,11 @@ String GDExtension::find_extension_library(const String &p_path, Ref class GDExtensionMethodBind : public MethodBind { GDExtensionClassMethodCall call_func; + GDExtensionClassMethodValidatedCall validated_call_func; GDExtensionClassMethodPtrCall ptrcall_func; void *method_userdata; bool vararg; + uint32_t argument_count; PropertyInfo return_value_info; GodotTypeInfo::Metadata return_value_metadata; List arguments_info; @@ -191,6 +193,40 @@ public: r_error.expected = ce.expected; return ret; } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { + ERR_FAIL_COND_MSG(vararg, "Validated methods don't have ptrcall support. This is most likely an engine bug."); + GDExtensionClassInstancePtr extension_instance = is_static() ? nullptr : p_object->_get_extension_instance(); + + if (validated_call_func) { + // This is added here, but it's unlikely to be provided by most extensions. + validated_call_func(method_userdata, extension_instance, reinterpret_cast(p_args), (GDExtensionVariantPtr)r_ret); + } else { +#if 1 + // Slow code-path, but works for the time being. + Callable::CallError ce; + call(p_object, p_args, argument_count, ce); +#else + // This is broken, because it needs more information to do the calling properly + + // If not provided, go via ptrcall, which is faster than resorting to regular call. + const void **argptrs = (const void **)alloca(argument_count * sizeof(void *)); + for (uint32_t i = 0; i < argument_count; i++) { + argptrs[i] = VariantInternal::get_opaque_pointer(p_args[i]); + } + + bool returns = true; + void *ret_opaque; + if (returns) { + ret_opaque = VariantInternal::get_opaque_pointer(r_ret); + } else { + ret_opaque = nullptr; // May be unnecessary as this is ignored, but just in case. + } + + ptrcall(p_object, argptrs, ret_opaque); +#endif + } + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { ERR_FAIL_COND_MSG(vararg, "Vararg methods don't have ptrcall support. This is most likely an engine bug."); GDExtensionClassInstancePtr extension_instance = p_object->_get_extension_instance(); @@ -204,6 +240,7 @@ public: explicit GDExtensionMethodBind(const GDExtensionClassMethodInfo *p_method_info) { method_userdata = p_method_info->method_userdata; call_func = p_method_info->call_func; + validated_call_func = nullptr; ptrcall_func = p_method_info->ptrcall_func; set_name(*reinterpret_cast(p_method_info->name)); @@ -218,7 +255,7 @@ public: } set_hint_flags(p_method_info->method_flags); - + argument_count = p_method_info->argument_count; vararg = p_method_info->method_flags & GDEXTENSION_METHOD_FLAG_VARARG; _set_returns(p_method_info->has_return_value); _set_const(p_method_info->method_flags & GDEXTENSION_METHOD_FLAG_CONST); diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index f323b2aa533..f1412d667f1 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -295,6 +295,7 @@ typedef enum { } GDExtensionClassMethodArgumentMetadata; typedef void (*GDExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); +typedef void (*GDExtensionClassMethodValidatedCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionVariantPtr r_return); typedef void (*GDExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); typedef struct { diff --git a/core/object/method_bind.h b/core/object/method_bind.h index d37479f45ba..84f0941b948 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -112,6 +112,8 @@ public: _FORCE_INLINE_ int get_argument_count() const { return argument_count; }; virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const = 0; + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const = 0; + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const = 0; StringName get_name() const; @@ -162,8 +164,12 @@ public: } #endif + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { + ERR_FAIL_MSG("Validated call can't be used with vararg methods. This is a bug."); + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { - ERR_FAIL(); // Can't call. + ERR_FAIL_MSG("ptrcall can't be used with vararg methods. This is a bug."); } virtual bool is_const() const { return false; } @@ -253,6 +259,7 @@ public: virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { return (static_cast(p_object)->*MethodBindVarArgBase, T, R, true>::method)(p_args, p_arg_count, r_error); } + #if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif @@ -326,6 +333,14 @@ public: return Variant(); } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { +#ifdef TYPED_METHOD_BIND + call_with_validated_object_instance_args(static_cast(p_object), method, p_args); +#else + call_with_validated_object_instance_args(reinterpret_cast(p_object), method, p_args); +#endif + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args(static_cast(p_object), method, p_args); @@ -393,6 +408,14 @@ public: return Variant(); } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { +#ifdef TYPED_METHOD_BIND + call_with_validated_object_instance_argsc(static_cast(p_object), method, p_args); +#else + call_with_validated_object_instance_argsc(reinterpret_cast(p_object), method, p_args); +#endif + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_argsc(static_cast(p_object), method, p_args); @@ -471,6 +494,14 @@ public: return ret; } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { +#ifdef TYPED_METHOD_BIND + call_with_validated_object_instance_args_ret(static_cast(p_object), method, p_args, r_ret); +#else + call_with_validated_object_instance_args_ret(reinterpret_cast(p_object), method, p_args, r_ret); +#endif + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args_ret(static_cast(p_object), method, p_args, r_ret); @@ -550,6 +581,14 @@ public: return ret; } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { +#ifdef TYPED_METHOD_BIND + call_with_validated_object_instance_args_retc(static_cast(p_object), method, p_args, r_ret); +#else + call_with_validated_object_instance_args_retc(reinterpret_cast(p_object), method, p_args, r_ret); +#endif + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args_retc(static_cast(p_object), method, p_args, r_ret); @@ -614,6 +653,10 @@ public: return Variant(); } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { + call_with_validated_variant_args_static_method(function, p_args); + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { (void)p_object; (void)r_ret; @@ -677,6 +720,10 @@ public: return ret; } + virtual void validated_call(Object *p_object, const Variant **p_args, Variant *r_ret) const override { + call_with_validated_variant_args_static_method_ret(function, p_args, r_ret); + } + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { (void)p_object; call_with_ptr_args_static_method_ret(function, p_args, r_ret); diff --git a/core/object/object.cpp b/core/object/object.cpp index aee6b2222d7..8ec385c0eb0 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -936,8 +936,8 @@ TypedArray Object::_get_method_list_bind() const { return ret; } -Vector Object::_get_meta_list_bind() const { - Vector _metaret; +TypedArray Object::_get_meta_list_bind() const { + TypedArray _metaret; for (const KeyValue &K : metadata) { _metaret.push_back(K.key); diff --git a/core/object/object.h b/core/object/object.h index 3bbc1fbc613..ed2c6254174 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -716,7 +716,7 @@ protected: return &_class_name_static; } - Vector _get_meta_list_bind() const; + TypedArray _get_meta_list_bind() const; TypedArray _get_property_list_bind() const; TypedArray _get_method_list_bind() const; diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index ed48f4065c5..cf0bd47bce7 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -295,4 +295,16 @@ struct GetTypeInfo &> { } }; +template +struct VariantInternalAccessor> { + static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } + static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::refcounted_object_assign(v, p_ref.ptr()); } +}; + +template +struct VariantInternalAccessor &> { + static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } + static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::refcounted_object_assign(v, p_ref.ptr()); } +}; + #endif // REF_COUNTED_H diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 81ac5adba71..9f8fb7e95ef 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -83,50 +83,60 @@ struct VariantCaster { } }; -#define VARIANT_ENUM_CAST(m_enum) \ - MAKE_ENUM_TYPE_INFO(m_enum) \ - template <> \ - struct VariantCaster { \ - static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \ - return (m_enum)p_variant.operator int64_t(); \ - } \ - }; \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \ - return m_enum(*reinterpret_cast(p_ptr)); \ - } \ - typedef int64_t EncodeT; \ - _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \ - *(int64_t *)p_ptr = (int64_t)p_val; \ - } \ - }; \ - template <> \ - struct ZeroInitializer { \ - static void initialize(m_enum &value) { value = (m_enum)0; } \ +#define VARIANT_ENUM_CAST(m_enum) \ + MAKE_ENUM_TYPE_INFO(m_enum) \ + template <> \ + struct VariantCaster { \ + static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \ + return (m_enum)p_variant.operator int64_t(); \ + } \ + }; \ + template <> \ + struct PtrToArg { \ + _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \ + return m_enum(*reinterpret_cast(p_ptr)); \ + } \ + typedef int64_t EncodeT; \ + _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \ + *(int64_t *)p_ptr = (int64_t)p_val; \ + } \ + }; \ + template <> \ + struct ZeroInitializer { \ + static void initialize(m_enum &value) { value = (m_enum)0; } \ + }; \ + template <> \ + struct VariantInternalAccessor { \ + static _FORCE_INLINE_ m_enum get(const Variant *v) { return m_enum(*VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, m_enum p_value) { *VariantInternal::get_int(v) = (int64_t)p_value; } \ }; -#define VARIANT_BITFIELD_CAST(m_enum) \ - MAKE_BITFIELD_TYPE_INFO(m_enum) \ - template <> \ - struct VariantCaster> { \ - static _FORCE_INLINE_ BitField cast(const Variant &p_variant) { \ - return BitField(p_variant.operator int64_t()); \ - } \ - }; \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static BitField convert(const void *p_ptr) { \ - return BitField(*reinterpret_cast(p_ptr)); \ - } \ - typedef int64_t EncodeT; \ - _FORCE_INLINE_ static void encode(BitField p_val, const void *p_ptr) { \ - *(int64_t *)p_ptr = p_val; \ - } \ - }; \ - template <> \ - struct ZeroInitializer> { \ - static void initialize(BitField &value) { value = 0; } \ +#define VARIANT_BITFIELD_CAST(m_enum) \ + MAKE_BITFIELD_TYPE_INFO(m_enum) \ + template <> \ + struct VariantCaster> { \ + static _FORCE_INLINE_ BitField cast(const Variant &p_variant) { \ + return BitField(p_variant.operator int64_t()); \ + } \ + }; \ + template <> \ + struct PtrToArg> { \ + _FORCE_INLINE_ static BitField convert(const void *p_ptr) { \ + return BitField(*reinterpret_cast(p_ptr)); \ + } \ + typedef int64_t EncodeT; \ + _FORCE_INLINE_ static void encode(BitField p_val, const void *p_ptr) { \ + *(int64_t *)p_ptr = p_val; \ + } \ + }; \ + template <> \ + struct ZeroInitializer> { \ + static void initialize(BitField &value) { value = 0; } \ + }; \ + template <> \ + struct VariantInternalAccessor> { \ + static _FORCE_INLINE_ BitField get(const Variant *v) { return BitField(*VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, BitField p_value) { *VariantInternal::get_int(v) = p_value.operator int64_t(); } \ }; // Object enum casts must go here @@ -597,6 +607,8 @@ void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_arg call_with_ptr_args_static_method_helper(p_method, p_args, BuildIndexSequence{}); } +// Validated + template void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) { call_with_validated_variant_args_helper(VariantGetInternalPtr::get_ptr(base), p_method, p_args, BuildIndexSequence{}); @@ -632,6 +644,38 @@ void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), con call_with_validated_variant_args_static_method_ret_helper(p_method, p_args, r_ret, BuildIndexSequence{}); } +// Validated Object + +template +void call_with_validated_object_instance_args(T *base, void (T::*p_method)(P...), const Variant **p_args) { + call_with_validated_variant_args_helper(base, p_method, p_args, BuildIndexSequence{}); +} + +template +void call_with_validated_object_instance_argsc(T *base, void (T::*p_method)(P...) const, const Variant **p_args) { + call_with_validated_variant_argsc_helper(base, p_method, p_args, BuildIndexSequence{}); +} + +template +void call_with_validated_object_instance_args_ret(T *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_ret_helper(base, p_method, p_args, r_ret, BuildIndexSequence{}); +} + +template +void call_with_validated_object_instance_args_retc(T *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_retc_helper(base, p_method, p_args, r_ret, BuildIndexSequence{}); +} + +template +void call_with_validated_object_instance_args_static(T *base, void (*p_method)(T *, P...), const Variant **p_args) { + call_with_validated_variant_args_static_helper(base, p_method, p_args, BuildIndexSequence{}); +} + +template +void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) { + call_with_validated_variant_args_static_retc_helper(base, p_method, p_args, r_ret, BuildIndexSequence{}); +} + // 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(__GNUC__) && !defined(__clang__) diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h index 03e557819b0..98afc7e717f 100644 --- a/core/variant/typed_array.h +++ b/core/variant/typed_array.h @@ -33,6 +33,7 @@ #include "core/object/object.h" #include "core/variant/array.h" +#include "core/variant/binder_common.h" #include "core/variant/method_ptrcall.h" #include "core/variant/type_info.h" #include "core/variant/variant.h" @@ -55,6 +56,17 @@ public: } }; +template +struct VariantInternalAccessor> { + static _FORCE_INLINE_ TypedArray get(const Variant *v) { return *VariantInternal::get_array(v); } + static _FORCE_INLINE_ void set(Variant *v, const TypedArray &p_array) { *VariantInternal::get_array(v) = p_array; } +}; +template +struct VariantInternalAccessor &> { + static _FORCE_INLINE_ TypedArray get(const Variant *v) { return *VariantInternal::get_array(v); } + static _FORCE_INLINE_ void set(Variant *v, const TypedArray &p_array) { *VariantInternal::get_array(v) = p_array; } +}; + //specialization for the rest of variant types #define MAKE_TYPED_ARRAY(m_type, m_variant_type) \ @@ -117,6 +129,7 @@ MAKE_TYPED_ARRAY(Vector, Variant::PACKED_STRING_ARRAY) MAKE_TYPED_ARRAY(Vector, Variant::PACKED_VECTOR2_ARRAY) MAKE_TYPED_ARRAY(Vector, Variant::PACKED_VECTOR3_ARRAY) MAKE_TYPED_ARRAY(Vector, Variant::PACKED_COLOR_ARRAY) +MAKE_TYPED_ARRAY(IPAddress, Variant::STRING) template struct PtrToArg> { @@ -215,5 +228,6 @@ MAKE_TYPED_ARRAY_INFO(Vector, Variant::PACKED_STRING_ARRAY) MAKE_TYPED_ARRAY_INFO(Vector, Variant::PACKED_VECTOR2_ARRAY) MAKE_TYPED_ARRAY_INFO(Vector, Variant::PACKED_VECTOR3_ARRAY) MAKE_TYPED_ARRAY_INFO(Vector, Variant::PACKED_COLOR_ARRAY) +MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING) #endif // TYPED_ARRAY_H diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 950f4a62d80..3427950224c 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -317,6 +317,17 @@ String Variant::get_constructor_argument_name(Variant::Type p_type, int p_constr return construct_data[p_type][p_constructor].arg_names[p_argument]; } +void VariantInternal::refcounted_object_assign(Variant *v, const RefCounted *rc) { + if (!rc || !const_cast(rc)->init_ref()) { + v->_get_obj().obj = nullptr; + v->_get_obj().id = ObjectID(); + return; + } + + v->_get_obj().obj = const_cast(rc); + v->_get_obj().id = rc->get_instance_id(); +} + void VariantInternal::object_assign(Variant *v, const Object *o) { if (o) { if (o->is_ref_counted()) { diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 0d55ee4ae2f..b7bd2a9c8c4 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -35,6 +35,9 @@ // For use when you want to access the internal pointer of a Variant directly. // Use with caution. You need to be sure that the type is correct. + +class RefCounted; + class VariantInternal { friend class Variant; @@ -320,6 +323,7 @@ public: } static void object_assign(Variant *v, const Object *o); // Needs RefCounted, so it's implemented elsewhere. + static void refcounted_object_assign(Variant *v, const RefCounted *rc); _FORCE_INLINE_ static void object_assign(Variant *v, const Variant *o) { object_assign(v, o->_get_obj().obj); @@ -820,30 +824,30 @@ VARIANT_ACCESSOR_NUMBER(int64_t) VARIANT_ACCESSOR_NUMBER(uint64_t) VARIANT_ACCESSOR_NUMBER(char32_t) -// Bind enums to allow using them as return types. -VARIANT_ACCESSOR_NUMBER(Error) -VARIANT_ACCESSOR_NUMBER(Side) -VARIANT_ACCESSOR_NUMBER(Vector2::Axis) -VARIANT_ACCESSOR_NUMBER(Vector2i::Axis) -VARIANT_ACCESSOR_NUMBER(Vector3::Axis) -VARIANT_ACCESSOR_NUMBER(Vector3i::Axis) -VARIANT_ACCESSOR_NUMBER(Vector4::Axis) -VARIANT_ACCESSOR_NUMBER(Vector4i::Axis) - -VARIANT_ACCESSOR_NUMBER(Projection::Planes) - -template <> -struct VariantInternalAccessor { - static _FORCE_INLINE_ EulerOrder get(const Variant *v) { return EulerOrder(*VariantInternal::get_int(v)); } - static _FORCE_INLINE_ void set(Variant *v, EulerOrder p_value) { *VariantInternal::get_int(v) = (int64_t)p_value; } -}; - template <> struct VariantInternalAccessor { static _FORCE_INLINE_ ObjectID get(const Variant *v) { return ObjectID(*VariantInternal::get_int(v)); } static _FORCE_INLINE_ void set(Variant *v, ObjectID p_value) { *VariantInternal::get_int(v) = p_value; } }; +template +struct VariantInternalAccessor { + static _FORCE_INLINE_ T *get(const Variant *v) { return const_cast(static_cast(*VariantInternal::get_object(v))); } + static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); } +}; + +template +struct VariantInternalAccessor { + static _FORCE_INLINE_ const T *get(const Variant *v) { return static_cast(*VariantInternal::get_object(v)); } + static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); } +}; + +template <> +struct VariantInternalAccessor { + static _FORCE_INLINE_ IPAddress get(const Variant *v) { return IPAddress(*VariantInternal::get_string(v)); } + static _FORCE_INLINE_ void set(Variant *v, IPAddress p_value) { *VariantInternal::get_string(v) = p_value; } +}; + template <> struct VariantInternalAccessor { static _FORCE_INLINE_ float get(const Variant *v) { return *VariantInternal::get_float(v); } diff --git a/doc/classes/AnimationNodeStateMachinePlayback.xml b/doc/classes/AnimationNodeStateMachinePlayback.xml index 1c9fe4b9f8c..48d4f154d1f 100644 --- a/doc/classes/AnimationNodeStateMachinePlayback.xml +++ b/doc/classes/AnimationNodeStateMachinePlayback.xml @@ -48,7 +48,7 @@ - + Returns the current travel path as computed internally by the A* algorithm. diff --git a/doc/classes/Geometry3D.xml b/doc/classes/Geometry3D.xml index 22df6f7a6e6..b2fb4251bba 100644 --- a/doc/classes/Geometry3D.xml +++ b/doc/classes/Geometry3D.xml @@ -88,7 +88,7 @@ - + Given a convex hull defined though the [Plane]s in the array [param planes], tests if the segment ([param from], [param to]) intersects with that hull. If an intersection is found, returns a [PackedVector3Array] containing the point the intersection and the hull's normal. Otherwise, returns an empty array. diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index eea01617995..619276b1549 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -597,7 +597,7 @@ - + Returns the object's metadata entry names as a [PackedStringArray]. diff --git a/doc/classes/RDShaderFile.xml b/doc/classes/RDShaderFile.xml index 3097573858c..98c719e6c8b 100644 --- a/doc/classes/RDShaderFile.xml +++ b/doc/classes/RDShaderFile.xml @@ -18,7 +18,7 @@ - + Returns the list of compiled versions for this shader. diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 61a24092a31..98e27307405 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -184,7 +184,7 @@ - + Starts a list of raster drawing commands created with the [code]draw_*[/code] methods. The returned value should be passed to other [code]draw_list_*[/code] functions. Multiple draw lists cannot be created at the same time; you must finish the previous draw list first using [method draw_list_end]. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 3dd9e8be0c0..3a4a25df6f7 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1497,7 +1497,7 @@ - + Returns the list of global shader uniform names. [b]Note:[/b] [method global_shader_parameter_get] has a large performance penalty as the rendering thread needs to synchronize with the calling thread, which is slow. Do not use this method during gameplay to avoid stuttering. If you need to read values in a script after setting them, consider creating an autoload where you store the values you need to query at the same time you're setting them as global parameters. diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index a919bbdc6e4..04452431c34 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -45,7 +45,7 @@ - + Inserts a triangle fan made of array data into [Mesh] being constructed. Requires the primitive type be set to [constant Mesh.PRIMITIVE_TRIANGLES]. diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index ad8d93a719e..f9aa14dd090 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -124,7 +124,7 @@ void ShaderFileEditor::_update_options() { int c = versions->get_current(); //remember current versions->clear(); - Vector version_list = shader_file->get_version_list(); + TypedArray version_list = shader_file->get_version_list(); if (c >= version_list.size()) { c = version_list.size() - 1; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 5ba861dc06f..071e2e7f37a 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -305,6 +305,10 @@ Vector AnimationNodeStateMachinePlayback::get_travel_path() const { return path; } +TypedArray AnimationNodeStateMachinePlayback::_get_travel_path() const { + return Variant(get_travel_path()).operator Array(); +} + float AnimationNodeStateMachinePlayback::get_current_play_pos() const { return pos_current; } @@ -1180,7 +1184,7 @@ void AnimationNodeStateMachinePlayback::_bind_methods() { ClassDB::bind_method(D_METHOD("get_current_play_position"), &AnimationNodeStateMachinePlayback::get_current_play_pos); ClassDB::bind_method(D_METHOD("get_current_length"), &AnimationNodeStateMachinePlayback::get_current_length); ClassDB::bind_method(D_METHOD("get_fading_from_node"), &AnimationNodeStateMachinePlayback::get_fading_from_node); - ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path); + ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::_get_travel_path); } AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() { diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index 757c6ddc68b..e45aae9e2ba 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -314,6 +314,8 @@ class AnimationNodeStateMachinePlayback : public Resource { Ref _get_group_start_transition() const; Ref _get_group_end_transition() const; + TypedArray _get_travel_path() const; + protected: static void _bind_methods(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 8a91e9f6e02..81192fa8d50 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -499,6 +499,10 @@ void Mesh::generate_debug_mesh_indices(Vector &r_points) { } } +Vector Mesh::_get_faces() const { + return Variant(get_faces()); +} + Vector Mesh::get_faces() const { Ref tm = generate_triangle_mesh(); if (tm.is_valid()) { @@ -793,6 +797,7 @@ void Mesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb); + ClassDB::bind_method(D_METHOD("get_faces"), &Mesh::_get_faces); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); @@ -2245,7 +2250,6 @@ void ArrayMesh::_bind_methods() { ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap); ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces); ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &ArrayMesh::generate_triangle_mesh); ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 4d9b9b40871..435655e80aa 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -50,6 +50,8 @@ class Mesh : public Resource { mutable Vector debug_lines; Size2i lightmap_size_hint; + Vector _get_faces() const; + public: enum PrimitiveType { PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS, diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 5ef3e09e3d1..c296523475d 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -374,6 +374,10 @@ void SurfaceTool::set_smooth_group(uint32_t p_group) { last_smooth_group = p_group; } +void SurfaceTool::_add_triangle_fan(const Vector &p_vertices, const Vector &p_uvs, const Vector &p_colors, const Vector &p_uv2s, const Vector &p_normals, const TypedArray &p_tangents) { + add_triangle_fan(p_vertices, p_uv2s, p_colors, p_uv2s, p_normals, Variant(p_tangents)); +} + void SurfaceTool::add_triangle_fan(const Vector &p_vertices, const Vector &p_uvs, const Vector &p_colors, const Vector &p_uv2s, const Vector &p_normals, const Vector &p_tangents) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES); @@ -1347,7 +1351,7 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom", "channel_index", "custom_color"), &SurfaceTool::set_custom); ClassDB::bind_method(D_METHOD("set_smooth_group", "index"), &SurfaceTool::set_smooth_group); - ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(Vector())); + ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::_add_triangle_fan, DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(Vector()), DEFVAL(TypedArray())); ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 77318bb061f..452aa835f01 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -167,6 +167,8 @@ private: static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, const int iFace, const int iVert); + void _add_triangle_fan(const Vector &p_vertices, const Vector &p_uvs = Vector(), const Vector &p_colors = Vector(), const Vector &p_uv2s = Vector(), const Vector &p_normals = Vector(), const TypedArray &p_tangents = TypedArray()); + protected: static void _bind_methods(); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 4ff8bbfb85b..0227f01f6f1 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -334,6 +334,14 @@ RID RenderingDevice::_compute_pipeline_create(RID p_shader, const TypedArray &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray &p_storage_textures) { + Vector stextures; + for (int i = 0; i < p_storage_textures.size(); i++) { + stextures.push_back(p_storage_textures[i]); + } + return draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, stextures); +} + Vector RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray &p_storage_textures) { Vector splits; splits.resize(p_splits); @@ -761,7 +769,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color())); - ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::draw_list_begin, DEFVAL(Vector()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray())); + ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::_draw_list_begin, DEFVAL(Vector()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray())); ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray())); ClassDB::bind_method(D_METHOD("draw_list_set_blend_constants", "draw_list", "color"), &RenderingDevice::draw_list_set_blend_constants); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 48246fa44a0..e55db0a2373 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -1330,6 +1330,7 @@ protected: RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref &p_rasterization_state, const Ref &p_multisample_state, const Ref &p_depth_stencil_state, const Ref &p_blend_state, BitField p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray &p_specialization_constants); RID _compute_pipeline_create(RID p_shader, const TypedArray &p_specialization_constants); + DrawListID _draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray &p_storage_textures = TypedArray()); Vector _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray &p_storage_textures = TypedArray()); void _draw_list_set_push_constant(DrawListID p_list, const Vector &p_data, uint32_t p_data_size); void _compute_list_set_push_constant(ComputeListID p_list, const Vector &p_data, uint32_t p_data_size); diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index 01d0f178c7b..e1734002991 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -349,13 +349,18 @@ public: return versions[p_version]->get_stages(); } - Vector get_version_list() const { + TypedArray get_version_list() const { Vector vnames; for (const KeyValue> &E : versions) { vnames.push_back(E.key); } vnames.sort_custom(); - return vnames; + TypedArray ret; + ret.resize(vnames.size()); + for (int i = 0; i < vnames.size(); i++) { + ret[i] = vnames[i]; + } + return ret; } void set_base_error(const String &p_error) { @@ -395,7 +400,7 @@ public: protected: Dictionary _get_versions() const { - Vector vnames = get_version_list(); + TypedArray vnames = get_version_list(); Dictionary ret; for (int i = 0; i < vnames.size(); i++) { ret[vnames[i]] = versions[vnames[i]]; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index fffe36bfb35..b8b642fac18 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2718,7 +2718,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_shader_parameter_add", "name", "type", "default_value"), &RenderingServer::global_shader_parameter_add); ClassDB::bind_method(D_METHOD("global_shader_parameter_remove", "name"), &RenderingServer::global_shader_parameter_remove); - ClassDB::bind_method(D_METHOD("global_shader_parameter_get_list"), &RenderingServer::global_shader_parameter_get_list); + ClassDB::bind_method(D_METHOD("global_shader_parameter_get_list"), &RenderingServer::_global_shader_parameter_get_list); ClassDB::bind_method(D_METHOD("global_shader_parameter_set", "name", "value"), &RenderingServer::global_shader_parameter_set); ClassDB::bind_method(D_METHOD("global_shader_parameter_set_override", "name", "value"), &RenderingServer::global_shader_parameter_set_override); ClassDB::bind_method(D_METHOD("global_shader_parameter_get", "name"), &RenderingServer::global_shader_parameter_get); @@ -2857,6 +2857,16 @@ RenderingServer::RenderingServer() { singleton = this; } +TypedArray RenderingServer::_global_shader_parameter_get_list() const { + TypedArray gsp; + Vector gsp_sn = global_shader_parameter_get_list(); + gsp.resize(gsp_sn.size()); + for (int i = 0; i < gsp_sn.size(); i++) { + gsp[i] = gsp_sn[i]; + } + return gsp; +} + void RenderingServer::init() { GLOBAL_DEF_RST_NOVAL_BASIC("rendering/textures/vram_compression/import_s3tc_bptc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_S3TC_BPTC); GLOBAL_DEF_RST_NOVAL_BASIC("rendering/textures/vram_compression/import_etc2_astc", OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_ETC2_ASTC); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 6206088b415..a5548db7431 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -57,6 +57,8 @@ class RenderingServer : public Object { const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON); const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON); + virtual TypedArray _global_shader_parameter_get_list() const; + protected: RID _make_test_cube(); void _free_internal_rids();