From 1c93606e470f0cad5f14af104ccb89a95a89931c Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 25 Apr 2023 00:21:32 +0200 Subject: [PATCH] Add ValidatedCall to MethodBind * This should optimize GDScript function calling _enormously_. * It also should simplify the GDScript VM considerably. NOTE: GDExtension calling performance has most likely been affected until going via ptrcall is fixed. --- core/core_bind.cpp | 5 +- core/core_bind.h | 2 +- core/extension/gdextension.cpp | 39 +++++- core/extension/gdextension_interface.h | 1 + core/object/method_bind.h | 49 ++++++- core/object/object.cpp | 4 +- core/object/object.h | 2 +- core/object/ref_counted.h | 12 ++ core/variant/binder_common.h | 128 ++++++++++++------ core/variant/typed_array.h | 14 ++ core/variant/variant_construct.cpp | 11 ++ core/variant/variant_internal.h | 40 +++--- .../AnimationNodeStateMachinePlayback.xml | 2 +- doc/classes/Geometry3D.xml | 2 +- doc/classes/Object.xml | 2 +- doc/classes/RDShaderFile.xml | 2 +- doc/classes/RenderingDevice.xml | 2 +- doc/classes/RenderingServer.xml | 2 +- doc/classes/SurfaceTool.xml | 2 +- editor/plugins/shader_file_editor_plugin.cpp | 2 +- .../animation_node_state_machine.cpp | 6 +- .../animation/animation_node_state_machine.h | 2 + scene/resources/mesh.cpp | 6 +- scene/resources/mesh.h | 2 + scene/resources/surface_tool.cpp | 6 +- scene/resources/surface_tool.h | 2 + servers/rendering/rendering_device.cpp | 10 +- servers/rendering/rendering_device.h | 1 + servers/rendering/rendering_device_binds.h | 11 +- servers/rendering_server.cpp | 12 +- servers/rendering_server.h | 2 + 31 files changed, 299 insertions(+), 84 deletions(-) diff --git a/core/core_bind.cpp b/core/core_bind.cpp index c7cd797f4d23..552bd2335856 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -965,10 +965,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 c7d597562aca..04642f464caa 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -323,7 +323,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 f158755a8560..91038b9bdf89 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 f323b2aa5335..f1412d667f1b 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 d37479f45ba7..84f0941b948f 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 39cae7c5bd1d..1775937b38b2 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -935,8 +935,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 4226b5e67b9e..99d05a78bb81 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -717,7 +717,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 ed48f4065c5e..cf0bd47bce7f 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 81ac5adba71a..9f8fb7e95efa 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 03e557819b02..98afc7e717ff 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 950f4a62d804..3427950224ce 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 0d55ee4ae2f4..b7bd2a9c8c4d 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 08634f650e5c..7d357a0f8303 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 22df6f7a6e6c..b2fb4251bba6 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 eea01617995f..619276b1549d 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 0d2217b50740..0a15e1048f06 100644 --- a/doc/classes/RDShaderFile.xml +++ b/doc/classes/RDShaderFile.xml @@ -14,7 +14,7 @@ - + diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index f597cb7efc65..ec25b0a515f0 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -152,7 +152,7 @@ - + diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 5f9abe2cda15..29a12467a85c 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1419,7 +1419,7 @@ - + diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index a919bbdc6e41..04452431c348 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 ad8d93a719e6..f9aa14dd090a 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 7f98bc1c98e2..a02dd7532ab5 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 757c6ddc68b5..e45aae9e2ba3 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 8a91e9f6e02f..81192fa8d50b 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 4d9b9b408712..435655e80aa7 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 ccb3ddee45c0..eaaf2b2115c3 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); @@ -1335,7 +1339,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 77318bb061f3..452aa835f016 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 744fd051f5e9..2d000cc9da1a 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); @@ -760,7 +768,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 447627b08ef0..97acb3e7fdc0 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -1329,6 +1329,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 01d0f178c7b8..e1734002991d 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 cc09825298a7..49617155cf41 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2716,7 +2716,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); @@ -2855,6 +2855,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 a28374444386..edf477157087 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();