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.
This commit is contained in:
Juan Linietsky 2023-04-25 00:21:32 +02:00
parent 14c582bca8
commit 1c93606e47
31 changed files with 299 additions and 84 deletions

View file

@ -965,10 +965,11 @@ Vector<Vector3> Geometry3D::segment_intersects_cylinder(const Vector3 &p_from, c
return r;
}
Vector<Vector3> Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
Vector<Vector3> Geometry3D::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray<Plane> &p_planes) {
Vector<Vector3> r;
Vector3 res, norm;
if (!::Geometry3D::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) {
Vector<Plane> planes = Variant(p_planes);
if (!::Geometry3D::segment_intersects_convex(p_from, p_to, planes.ptr(), planes.size(), &res, &norm)) {
return r;
}

View file

@ -323,7 +323,7 @@ public:
Vector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
Vector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
Vector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
Vector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray<Plane> &p_planes);
Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane);

View file

@ -146,9 +146,11 @@ String GDExtension::find_extension_library(const String &p_path, Ref<ConfigFile>
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<PropertyInfo> 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<GDExtensionConstVariantPtr *>(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<StringName *>(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);

View file

@ -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 {

View file

@ -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<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, 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<T *>(p_object), method, p_args);
#else
call_with_validated_object_instance_args(reinterpret_cast<MB_T *>(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<T, P...>(static_cast<T *>(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<T *>(p_object), method, p_args);
#else
call_with_validated_object_instance_argsc(reinterpret_cast<MB_T *>(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<T, P...>(static_cast<T *>(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<T *>(p_object), method, p_args, r_ret);
#else
call_with_validated_object_instance_args_ret(reinterpret_cast<MB_T *>(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<T, R, P...>(static_cast<T *>(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<T *>(p_object), method, p_args, r_ret);
#else
call_with_validated_object_instance_args_retc(reinterpret_cast<MB_T *>(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<T, R, P...>(static_cast<T *>(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);

View file

@ -935,8 +935,8 @@ TypedArray<Dictionary> Object::_get_method_list_bind() const {
return ret;
}
Vector<StringName> Object::_get_meta_list_bind() const {
Vector<StringName> _metaret;
TypedArray<StringName> Object::_get_meta_list_bind() const {
TypedArray<StringName> _metaret;
for (const KeyValue<StringName, Variant> &K : metadata) {
_metaret.push_back(K.key);

View file

@ -717,7 +717,7 @@ protected:
return &_class_name_static;
}
Vector<StringName> _get_meta_list_bind() const;
TypedArray<StringName> _get_meta_list_bind() const;
TypedArray<Dictionary> _get_property_list_bind() const;
TypedArray<Dictionary> _get_method_list_bind() const;

View file

@ -295,4 +295,16 @@ struct GetTypeInfo<const Ref<T> &> {
}
};
template <class T>
struct VariantInternalAccessor<Ref<T>> {
static _FORCE_INLINE_ Ref<T> get(const Variant *v) { return Ref<T>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const Ref<T> &p_ref) { VariantInternal::refcounted_object_assign(v, p_ref.ptr()); }
};
template <class T>
struct VariantInternalAccessor<const Ref<T> &> {
static _FORCE_INLINE_ Ref<T> get(const Variant *v) { return Ref<T>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const Ref<T> &p_ref) { VariantInternal::refcounted_object_assign(v, p_ref.ptr()); }
};
#endif // REF_COUNTED_H

View file

@ -83,50 +83,60 @@ struct VariantCaster<const T &> {
}
};
#define VARIANT_ENUM_CAST(m_enum) \
MAKE_ENUM_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<m_enum> { \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_enum> { \
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
return m_enum(*reinterpret_cast<const int64_t *>(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<m_enum> { \
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<m_enum> { \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_enum> { \
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
return m_enum(*reinterpret_cast<const int64_t *>(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<m_enum> { \
static void initialize(m_enum &value) { value = (m_enum)0; } \
}; \
template <> \
struct VariantInternalAccessor<m_enum> { \
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<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
return BitField<m_enum>(p_variant.operator int64_t()); \
} \
}; \
template <> \
struct PtrToArg<BitField<m_enum>> { \
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
*(int64_t *)p_ptr = p_val; \
} \
}; \
template <> \
struct ZeroInitializer<BitField<m_enum>> { \
static void initialize(BitField<m_enum> &value) { value = 0; } \
#define VARIANT_BITFIELD_CAST(m_enum) \
MAKE_BITFIELD_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
return BitField<m_enum>(p_variant.operator int64_t()); \
} \
}; \
template <> \
struct PtrToArg<BitField<m_enum>> { \
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
*(int64_t *)p_ptr = p_val; \
} \
}; \
template <> \
struct ZeroInitializer<BitField<m_enum>> { \
static void initialize(BitField<m_enum> &value) { value = 0; } \
}; \
template <> \
struct VariantInternalAccessor<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> get(const Variant *v) { return BitField<m_enum>(*VariantInternal::get_int(v)); } \
static _FORCE_INLINE_ void set(Variant *v, BitField<m_enum> 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...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
// Validated
template <class T, class... P>
void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
@ -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<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
// Validated Object
template <class T, class... P>
void call_with_validated_object_instance_args(T *base, void (T::*p_method)(P...), const Variant **p_args) {
call_with_validated_variant_args_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
template <class T, class... P>
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<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
template <class T, class R, class... P>
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<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
template <class T, class R, class... P>
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<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
template <class T, class... P>
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<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
template <class T, class R, class... P>
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<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
// GCC raises "parameter 'p_args' set but not used" when P = {},
// it's not clever enough to treat other P values as making this branch valid.
#if defined(__GNUC__) && !defined(__clang__)

View file

@ -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 <class T>
struct VariantInternalAccessor<TypedArray<T>> {
static _FORCE_INLINE_ TypedArray<T> get(const Variant *v) { return *VariantInternal::get_array(v); }
static _FORCE_INLINE_ void set(Variant *v, const TypedArray<T> &p_array) { *VariantInternal::get_array(v) = p_array; }
};
template <class T>
struct VariantInternalAccessor<const TypedArray<T> &> {
static _FORCE_INLINE_ TypedArray<T> get(const Variant *v) { return *VariantInternal::get_array(v); }
static _FORCE_INLINE_ void set(Variant *v, const TypedArray<T> &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<String>, Variant::PACKED_STRING_ARRAY)
MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
template <class T>
struct PtrToArg<TypedArray<T>> {
@ -215,5 +228,6 @@ MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
#endif // TYPED_ARRAY_H

View file

@ -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<RefCounted *>(rc)->init_ref()) {
v->_get_obj().obj = nullptr;
v->_get_obj().id = ObjectID();
return;
}
v->_get_obj().obj = const_cast<RefCounted *>(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()) {

View file

@ -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<EulerOrder> {
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<ObjectID> {
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 <class T>
struct VariantInternalAccessor<T *> {
static _FORCE_INLINE_ T *get(const Variant *v) { return const_cast<T *>(static_cast<const T *>(*VariantInternal::get_object(v))); }
static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); }
};
template <class T>
struct VariantInternalAccessor<const T *> {
static _FORCE_INLINE_ const T *get(const Variant *v) { return static_cast<const T *>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); }
};
template <>
struct VariantInternalAccessor<IPAddress> {
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<float> {
static _FORCE_INLINE_ float get(const Variant *v) { return *VariantInternal::get_float(v); }

View file

@ -48,7 +48,7 @@
</description>
</method>
<method name="get_travel_path" qualifiers="const">
<return type="PackedStringArray" />
<return type="StringName[]" />
<description>
Returns the current travel path as computed internally by the A* algorithm.
</description>

View file

@ -88,7 +88,7 @@
<return type="PackedVector3Array" />
<param index="0" name="from" type="Vector3" />
<param index="1" name="to" type="Vector3" />
<param index="2" name="planes" type="Array" />
<param index="2" name="planes" type="Plane[]" />
<description>
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.
</description>

View file

@ -597,7 +597,7 @@
</description>
</method>
<method name="get_meta_list" qualifiers="const">
<return type="PackedStringArray" />
<return type="StringName[]" />
<description>
Returns the object's metadata entry names as a [PackedStringArray].
</description>

View file

@ -14,7 +14,7 @@
</description>
</method>
<method name="get_version_list" qualifiers="const">
<return type="PackedStringArray" />
<return type="StringName[]" />
<description>
</description>
</method>

View file

@ -152,7 +152,7 @@
<param index="6" name="clear_depth" type="float" default="1.0" />
<param index="7" name="clear_stencil" type="int" default="0" />
<param index="8" name="region" type="Rect2" default="Rect2(0, 0, 0, 0)" />
<param index="9" name="storage_textures" type="Array" default="[]" />
<param index="9" name="storage_textures" type="RID[]" default="[]" />
<description>
</description>
</method>

View file

@ -1419,7 +1419,7 @@
</description>
</method>
<method name="global_shader_parameter_get_list" qualifiers="const">
<return type="PackedStringArray" />
<return type="StringName[]" />
<description>
</description>
</method>

View file

@ -45,7 +45,7 @@
<param index="2" name="colors" type="PackedColorArray" default="PackedColorArray()" />
<param index="3" name="uv2s" type="PackedVector2Array" default="PackedVector2Array()" />
<param index="4" name="normals" type="PackedVector3Array" default="PackedVector3Array()" />
<param index="5" name="tangents" type="Array" default="[]" />
<param index="5" name="tangents" type="Plane[]" default="[]" />
<description>
Inserts a triangle fan made of array data into [Mesh] being constructed.
Requires the primitive type be set to [constant Mesh.PRIMITIVE_TRIANGLES].

View file

@ -124,7 +124,7 @@ void ShaderFileEditor::_update_options() {
int c = versions->get_current();
//remember current
versions->clear();
Vector<StringName> version_list = shader_file->get_version_list();
TypedArray<StringName> version_list = shader_file->get_version_list();
if (c >= version_list.size()) {
c = version_list.size() - 1;

View file

@ -305,6 +305,10 @@ Vector<StringName> AnimationNodeStateMachinePlayback::get_travel_path() const {
return path;
}
TypedArray<StringName> 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() {

View file

@ -314,6 +314,8 @@ class AnimationNodeStateMachinePlayback : public Resource {
Ref<AnimationNodeStateMachineTransition> _get_group_start_transition() const;
Ref<AnimationNodeStateMachineTransition> _get_group_end_transition() const;
TypedArray<StringName> _get_travel_path() const;
protected:
static void _bind_methods();

View file

@ -499,6 +499,10 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
}
}
Vector<Vector3> Mesh::_get_faces() const {
return Variant(get_faces());
}
Vector<Face3> Mesh::get_faces() const {
Ref<TriangleMesh> 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);

View file

@ -50,6 +50,8 @@ class Mesh : public Resource {
mutable Vector<Vector3> debug_lines;
Size2i lightmap_size_hint;
Vector<Vector3> _get_faces() const;
public:
enum PrimitiveType {
PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS,

View file

@ -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<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const TypedArray<Plane> &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<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &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<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>()));
ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::_add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(TypedArray<Plane>()));
ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index);

View file

@ -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<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const TypedArray<Plane> &p_tangents = TypedArray<Plane>());
protected:
static void _bind_methods();

View file

@ -334,6 +334,14 @@ RID RenderingDevice::_compute_pipeline_create(RID p_shader, const TypedArray<RDP
return compute_pipeline_create(p_shader, _get_spec_constants(p_specialization_constants));
}
RenderingDevice::DrawListID RenderingDevice::_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<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
Vector<RID> 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<int64_t> 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<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
Vector<DrawListID> 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<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
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<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
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<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
ClassDB::bind_method(D_METHOD("draw_list_set_blend_constants", "draw_list", "color"), &RenderingDevice::draw_list_set_blend_constants);

View file

@ -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<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, BitField<PipelineDynamicStateFlags> p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
RID _compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &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<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
Vector<int64_t> _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<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);

View file

@ -349,13 +349,18 @@ public:
return versions[p_version]->get_stages();
}
Vector<StringName> get_version_list() const {
TypedArray<StringName> get_version_list() const {
Vector<StringName> vnames;
for (const KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) {
vnames.push_back(E.key);
}
vnames.sort_custom<StringName::AlphCompare>();
return vnames;
TypedArray<StringName> 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<StringName> vnames = get_version_list();
TypedArray<StringName> vnames = get_version_list();
Dictionary ret;
for (int i = 0; i < vnames.size(); i++) {
ret[vnames[i]] = versions[vnames[i]];

View file

@ -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<StringName> RenderingServer::_global_shader_parameter_get_list() const {
TypedArray<StringName> gsp;
Vector<StringName> 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);

View file

@ -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<StringName> _global_shader_parameter_get_list() const;
protected:
RID _make_test_cube();
void _free_internal_rids();