diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp index 39a5f05d..40693aa7 100644 --- a/include/godot_cpp/godot.hpp +++ b/include/godot_cpp/godot.hpp @@ -88,6 +88,7 @@ extern "C" GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_c extern "C" GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict; extern "C" GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor; extern "C" GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor; +extern "C" GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter; extern "C" GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator; extern "C" GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method; extern "C" GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor; diff --git a/include/godot_cpp/variant/variant.hpp b/include/godot_cpp/variant/variant.hpp index 4c5f206a..f6b70523 100644 --- a/include/godot_cpp/variant/variant.hpp +++ b/include/godot_cpp/variant/variant.hpp @@ -49,6 +49,7 @@ class Variant { friend class GDExtensionBinding; friend class MethodBind; + friend class VariantInternal; static void init_bindings(); diff --git a/include/godot_cpp/variant/variant_internal.hpp b/include/godot_cpp/variant/variant_internal.hpp new file mode 100644 index 00000000..56b73038 --- /dev/null +++ b/include/godot_cpp/variant/variant_internal.hpp @@ -0,0 +1,510 @@ +/**************************************************************************/ +/* variant_internal.hpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef GODOT_VARIANT_INTERNAL_HPP +#define GODOT_VARIANT_INTERNAL_HPP + +#include +#include +#include + +namespace godot { +// 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. + +namespace internal { +template +struct VariantInternalType {}; + +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::BOOL; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::INT; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::FLOAT; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::STRING; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR2; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR2I; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::RECT2; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::RECT2I; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR3; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR3I; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::TRANSFORM2D; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR4; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::VECTOR4I; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PLANE; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::QUATERNION; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::AABB; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::BASIS; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::TRANSFORM3D; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PROJECTION; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::COLOR; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::STRING_NAME; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::NODE_PATH; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::RID; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::OBJECT; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::CALLABLE; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::SIGNAL; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::DICTIONARY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_BYTE_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_INT32_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_INT64_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_FLOAT32_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_FLOAT64_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_STRING_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_VECTOR2_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_VECTOR3_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_COLOR_ARRAY; +}; +template <> +struct VariantInternalType { + static constexpr Variant::Type type = Variant::PACKED_VECTOR4_ARRAY; +}; +} //namespace internal + +class VariantInternal { + friend class Variant; + + static GDExtensionVariantGetInternalPtrFunc get_internal_func[Variant::VARIANT_MAX]; + + static void init_bindings(); + +public: + template + _FORCE_INLINE_ static T *get_internal_value(Variant *v) { + return static_cast(get_internal_func[internal::VariantInternalType::type](v)); + } + + template + _FORCE_INLINE_ static const T *get_internal_value(const Variant *v) { + return static_cast(get_internal_func[internal::VariantInternalType::type](const_cast(v))); + } + + // Atomic types. + _FORCE_INLINE_ static bool *get_bool(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const bool *get_bool(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static int64_t *get_int(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const int64_t *get_int(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static double *get_float(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const double *get_float(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static String *get_string(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const String *get_string(const Variant *v) { return get_internal_value(v); } + + // Math types. + _FORCE_INLINE_ static Vector2 *get_vector2(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector2 *get_vector2(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Vector2i *get_vector2i(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector2i *get_vector2i(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Rect2 *get_rect2(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Rect2 *get_rect2(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Rect2i *get_rect2i(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Rect2i *get_rect2i(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Vector3 *get_vector3(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Vector4 *get_vector4(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector4 *get_vector4(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Vector4i *get_vector4i(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Vector4i *get_vector4i(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Plane *get_plane(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Plane *get_plane(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Quaternion *get_quaternion(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Quaternion *get_quaternion(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static AABB *get_aabb(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const AABB *get_aabb(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Basis *get_basis(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Projection *get_projection(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Projection *get_projection(const Variant *v) { return get_internal_value(v); } + + // Misc types. + _FORCE_INLINE_ static Color *get_color(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Color *get_color(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static StringName *get_string_name(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const StringName *get_string_name(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static NodePath *get_node_path(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const NodePath *get_node_path(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static RID *get_rid(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const RID *get_rid(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Callable *get_callable(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Callable *get_callable(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Signal *get_signal(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Signal *get_signal(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Dictionary *get_dictionary(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Dictionary *get_dictionary(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static Array *get_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Array *get_array(const Variant *v) { return get_internal_value(v); } + + // Typed arrays. + _FORCE_INLINE_ static PackedByteArray *get_byte_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedByteArray *get_byte_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedInt32Array *get_int32_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedInt32Array *get_int32_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedInt64Array *get_int64_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedInt64Array *get_int64_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedFloat32Array *get_float32_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedFloat32Array *get_float32_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedFloat64Array *get_float64_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedFloat64Array *get_float64_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedStringArray *get_string_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedStringArray *get_string_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedVector2Array *get_vector2_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedVector2Array *get_vector2_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedVector3Array *get_vector3_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedVector3Array *get_vector3_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedColorArray *get_color_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedColorArray *get_color_array(const Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static PackedVector4Array *get_vector4_array(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const PackedVector4Array *get_vector4_array(const Variant *v) { return get_internal_value(v); } + + _FORCE_INLINE_ static Object **get_object(Variant *v) { return get_internal_value(v); } + _FORCE_INLINE_ static const Object **get_object(const Variant *v) { return (const Object **)get_internal_value(v); } + + _FORCE_INLINE_ static void *get_opaque_pointer(Variant *v) { + switch (v->get_type()) { + case Variant::NIL: + return nullptr; + case Variant::BOOL: + return get_bool(v); + case Variant::INT: + return get_int(v); + case Variant::FLOAT: + return get_float(v); + case Variant::STRING: + return get_string(v); + case Variant::VECTOR2: + return get_vector2(v); + case Variant::VECTOR2I: + return get_vector2i(v); + case Variant::VECTOR3: + return get_vector3(v); + case Variant::VECTOR3I: + return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); + case Variant::RECT2: + return get_rect2(v); + case Variant::RECT2I: + return get_rect2i(v); + case Variant::TRANSFORM3D: + return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); + case Variant::TRANSFORM2D: + return get_transform2d(v); + case Variant::QUATERNION: + return get_quaternion(v); + case Variant::PLANE: + return get_plane(v); + case Variant::BASIS: + return get_basis(v); + case Variant::AABB: + return get_aabb(v); + case Variant::COLOR: + return get_color(v); + case Variant::STRING_NAME: + return get_string_name(v); + case Variant::NODE_PATH: + return get_node_path(v); + case Variant::RID: + return get_rid(v); + case Variant::CALLABLE: + return get_callable(v); + case Variant::SIGNAL: + return get_signal(v); + case Variant::DICTIONARY: + return get_dictionary(v); + case Variant::ARRAY: + return get_array(v); + case Variant::PACKED_BYTE_ARRAY: + return get_byte_array(v); + case Variant::PACKED_INT32_ARRAY: + return get_int32_array(v); + case Variant::PACKED_INT64_ARRAY: + return get_int64_array(v); + case Variant::PACKED_FLOAT32_ARRAY: + return get_float32_array(v); + case Variant::PACKED_FLOAT64_ARRAY: + return get_float64_array(v); + case Variant::PACKED_STRING_ARRAY: + return get_string_array(v); + case Variant::PACKED_VECTOR2_ARRAY: + return get_vector2_array(v); + case Variant::PACKED_VECTOR3_ARRAY: + return get_vector3_array(v); + case Variant::PACKED_COLOR_ARRAY: + return get_color_array(v); + case Variant::PACKED_VECTOR4_ARRAY: + return get_vector4_array(v); + case Variant::OBJECT: + return get_object(v); + case Variant::VARIANT_MAX: + ERR_FAIL_V(nullptr); + } + ERR_FAIL_V(nullptr); + } + + _FORCE_INLINE_ static const void *get_opaque_pointer(const Variant *v) { + switch (v->get_type()) { + case Variant::NIL: + return nullptr; + case Variant::BOOL: + return get_bool(v); + case Variant::INT: + return get_int(v); + case Variant::FLOAT: + return get_float(v); + case Variant::STRING: + return get_string(v); + case Variant::VECTOR2: + return get_vector2(v); + case Variant::VECTOR2I: + return get_vector2i(v); + case Variant::VECTOR3: + return get_vector3(v); + case Variant::VECTOR3I: + return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); + case Variant::RECT2: + return get_rect2(v); + case Variant::RECT2I: + return get_rect2i(v); + case Variant::TRANSFORM3D: + return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); + case Variant::TRANSFORM2D: + return get_transform2d(v); + case Variant::QUATERNION: + return get_quaternion(v); + case Variant::PLANE: + return get_plane(v); + case Variant::BASIS: + return get_basis(v); + case Variant::AABB: + return get_aabb(v); + case Variant::COLOR: + return get_color(v); + case Variant::STRING_NAME: + return get_string_name(v); + case Variant::NODE_PATH: + return get_node_path(v); + case Variant::RID: + return get_rid(v); + case Variant::CALLABLE: + return get_callable(v); + case Variant::SIGNAL: + return get_signal(v); + case Variant::DICTIONARY: + return get_dictionary(v); + case Variant::ARRAY: + return get_array(v); + case Variant::PACKED_BYTE_ARRAY: + return get_byte_array(v); + case Variant::PACKED_INT32_ARRAY: + return get_int32_array(v); + case Variant::PACKED_INT64_ARRAY: + return get_int64_array(v); + case Variant::PACKED_FLOAT32_ARRAY: + return get_float32_array(v); + case Variant::PACKED_FLOAT64_ARRAY: + return get_float64_array(v); + case Variant::PACKED_STRING_ARRAY: + return get_string_array(v); + case Variant::PACKED_VECTOR2_ARRAY: + return get_vector2_array(v); + case Variant::PACKED_VECTOR3_ARRAY: + return get_vector3_array(v); + case Variant::PACKED_COLOR_ARRAY: + return get_color_array(v); + case Variant::PACKED_VECTOR4_ARRAY: + return get_vector4_array(v); + case Variant::OBJECT: + return get_object(v); + case Variant::VARIANT_MAX: + ERR_FAIL_V(nullptr); + } + ERR_FAIL_V(nullptr); + } +}; + +template +struct VariantGetInternalPtr { + static internal::VariantInternalType *get_ptr(Variant *v) { return VariantInternal::get_internal_value(v); } + static const internal::VariantInternalType *get_ptr(const Variant *v) { return VariantInternal::get_internal_value(v); } +}; + +template +struct can_set_variant_internal_value { + static const bool value = true; +}; + +template <> +struct can_set_variant_internal_value { + static const bool value = false; +}; + +template +struct VariantInternalAccessor { + static _FORCE_INLINE_ const T &get(const Variant *v) { return *VariantInternal::get_internal_value(v); } + + // Enable set() only for those types where we can set (all but Object *). + template ::value>> + static _FORCE_INLINE_ void set(Variant *v, const internal::VariantInternalType &p_value) { + *VariantInternal::get_internal_value(v) = p_value; + } +}; + +template ::value>> +struct VariantDefaultInitializer { + static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_internal_value(v) = T(); } +}; + +} // namespace godot + +#endif // GODOT_VARIANT_INTERNAL_HPP diff --git a/src/godot.cpp b/src/godot.cpp index fe75e6e9..31a64c46 100644 --- a/src/godot.cpp +++ b/src/godot.cpp @@ -94,6 +94,7 @@ GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict = nullptr; GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor = nullptr; GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor = nullptr; +GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter = nullptr; GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator = nullptr; GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method = nullptr; GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor = nullptr; @@ -375,6 +376,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge LOAD_PROC_ADDRESS(variant_can_convert_strict, GDExtensionInterfaceVariantCanConvertStrict); LOAD_PROC_ADDRESS(get_variant_from_type_constructor, GDExtensionInterfaceGetVariantFromTypeConstructor); LOAD_PROC_ADDRESS(get_variant_to_type_constructor, GDExtensionInterfaceGetVariantToTypeConstructor); + LOAD_PROC_ADDRESS(variant_get_ptr_internal_getter, GDExtensionInterfaceGetVariantGetInternalPtrFunc); LOAD_PROC_ADDRESS(variant_get_ptr_operator_evaluator, GDExtensionInterfaceVariantGetPtrOperatorEvaluator); LOAD_PROC_ADDRESS(variant_get_ptr_builtin_method, GDExtensionInterfaceVariantGetPtrBuiltinMethod); LOAD_PROC_ADDRESS(variant_get_ptr_constructor, GDExtensionInterfaceVariantGetPtrConstructor); diff --git a/src/variant/variant.cpp b/src/variant/variant.cpp index 1f57d48a..cf8323ab 100644 --- a/src/variant/variant.cpp +++ b/src/variant/variant.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -49,6 +50,7 @@ void Variant::init_bindings() { from_type_constructor[i] = internal::gdextension_interface_get_variant_from_type_constructor((GDExtensionVariantType)i); to_type_constructor[i] = internal::gdextension_interface_get_variant_to_type_constructor((GDExtensionVariantType)i); } + VariantInternal::init_bindings(); StringName::init_bindings(); String::init_bindings(); diff --git a/src/variant/variant_internal.cpp b/src/variant/variant_internal.cpp new file mode 100644 index 00000000..fbfd1cfb --- /dev/null +++ b/src/variant/variant_internal.cpp @@ -0,0 +1,43 @@ +/**************************************************************************/ +/* variant_internal.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include + +namespace godot { + +GDExtensionVariantGetInternalPtrFunc VariantInternal::get_internal_func[Variant::VARIANT_MAX]{}; + +void VariantInternal::init_bindings() { + for (int i = 1; i < Variant::VARIANT_MAX; i++) { + get_internal_func[i] = internal::gdextension_interface_variant_get_ptr_internal_getter((GDExtensionVariantType)i); + } +} + +} // namespace godot diff --git a/test/project/main.gd b/test/project/main.gd index e5a3b95c..b69ad75a 100644 --- a/test/project/main.gd +++ b/test/project/main.gd @@ -271,6 +271,9 @@ func _ready(): # Test that we can access an engine singleton. assert_equal(example.test_use_engine_singleton(), OS.get_name()) + assert_equal(example.test_get_internal(1), 1) + assert_equal(example.test_get_internal(true), -1) + # Test that notifications happen on both parent and child classes. var example_child = $ExampleChild assert_equal(example_child.get_value1(), 11) diff --git a/test/src/example.cpp b/test/src/example.cpp index 22739b29..4bd3d974 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -243,6 +243,8 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind); ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize); + ClassDB::bind_method(D_METHOD("test_get_internal", "a"), &Example::test_get_internal); + GDVIRTUAL_BIND(_do_something_virtual, "name", "value"); ClassDB::bind_method(D_METHOD("test_virtual_implemented_in_script"), &Example::test_virtual_implemented_in_script); GDVIRTUAL_BIND(_do_something_virtual_with_control, "control"); @@ -741,6 +743,14 @@ String Example::test_library_path() { return library_path; } +int64_t Example::test_get_internal(const Variant &p_input) const { + if (p_input.get_type() != Variant::INT) { + return -1; + } + + return *VariantInternal::get_int(&p_input); +} + void ExampleRuntime::_bind_methods() { ClassDB::bind_method(D_METHOD("set_prop_value", "value"), &ExampleRuntime::set_prop_value); ClassDB::bind_method(D_METHOD("get_prop_value"), &ExampleRuntime::get_prop_value); diff --git a/test/src/example.h b/test/src/example.h index a7ae54c0..cd5e9f84 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -185,6 +186,8 @@ public: bool test_post_initialize() const; + int64_t test_get_internal(const Variant &p_input) const; + // Static method. static int test_static(int p_a, int p_b); static void test_static2();