diff options
author | Lukas Tenbrink <lukas.tenbrink@gmail.com> | 2024-11-13 22:27:34 +0100 |
---|---|---|
committer | Lukas Tenbrink <lukas.tenbrink@gmail.com> | 2024-11-26 02:19:03 +0100 |
commit | ffd4de67d0c82b335d36abd635892e065469eea4 (patch) | |
tree | d4dffc2ae0e485737d5813020a27ca2bec44dacc | |
parent | 76fa7b291455a8ba24c50005072ebdb58f8a5984 (diff) | |
download | redot-engine-ffd4de67d0c82b335d36abd635892e065469eea4.tar.gz |
Add variant_get_ptr_internal_getter to gdextension_interface.h. The function returns functions to retrieve a pointer to a Variant's internal value. This enables GDExtensions to implement functionality similar to VariantGetInternalPtr, to access Variant internal values directly.
-rw-r--r-- | core/extension/gdextension_interface.cpp | 86 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 18 |
2 files changed, 104 insertions, 0 deletions
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index 203f7960dc..85d53c31ec 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -700,6 +700,91 @@ static GDExtensionTypeFromVariantConstructorFunc gdextension_get_variant_to_type ERR_FAIL_V_MSG(nullptr, "Getting Variant conversion function with invalid type"); } +static GDExtensionVariantGetInternalPtrFunc gdextension_variant_get_ptr_internal_getter(GDExtensionVariantType p_type) { + switch (p_type) { + case GDEXTENSION_VARIANT_TYPE_BOOL: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<bool *(*)(Variant *)>(VariantInternal::get_bool)); + case GDEXTENSION_VARIANT_TYPE_INT: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<int64_t *(*)(Variant *)>(VariantInternal::get_int)); + case GDEXTENSION_VARIANT_TYPE_FLOAT: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<double *(*)(Variant *)>(VariantInternal::get_float)); + case GDEXTENSION_VARIANT_TYPE_STRING: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<String *(*)(Variant *)>(VariantInternal::get_string)); + case GDEXTENSION_VARIANT_TYPE_VECTOR2: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector2 *(*)(Variant *)>(VariantInternal::get_vector2)); + case GDEXTENSION_VARIANT_TYPE_VECTOR2I: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector2i *(*)(Variant *)>(VariantInternal::get_vector2i)); + case GDEXTENSION_VARIANT_TYPE_RECT2: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Rect2 *(*)(Variant *)>(VariantInternal::get_rect2)); + case GDEXTENSION_VARIANT_TYPE_RECT2I: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Rect2i *(*)(Variant *)>(VariantInternal::get_rect2i)); + case GDEXTENSION_VARIANT_TYPE_VECTOR3: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector3 *(*)(Variant *)>(VariantInternal::get_vector3)); + case GDEXTENSION_VARIANT_TYPE_VECTOR3I: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector3i *(*)(Variant *)>(VariantInternal::get_vector3i)); + case GDEXTENSION_VARIANT_TYPE_TRANSFORM2D: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Transform2D *(*)(Variant *)>(VariantInternal::get_transform2d)); + case GDEXTENSION_VARIANT_TYPE_VECTOR4: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector4 *(*)(Variant *)>(VariantInternal::get_vector4)); + case GDEXTENSION_VARIANT_TYPE_VECTOR4I: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Vector4i *(*)(Variant *)>(VariantInternal::get_vector4i)); + case GDEXTENSION_VARIANT_TYPE_PLANE: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Plane *(*)(Variant *)>(VariantInternal::get_plane)); + case GDEXTENSION_VARIANT_TYPE_QUATERNION: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Quaternion *(*)(Variant *)>(VariantInternal::get_quaternion)); + case GDEXTENSION_VARIANT_TYPE_AABB: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<AABB *(*)(Variant *)>(VariantInternal::get_aabb)); + case GDEXTENSION_VARIANT_TYPE_BASIS: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Basis *(*)(Variant *)>(VariantInternal::get_basis)); + case GDEXTENSION_VARIANT_TYPE_TRANSFORM3D: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Transform3D *(*)(Variant *)>(VariantInternal::get_transform)); + case GDEXTENSION_VARIANT_TYPE_PROJECTION: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Projection *(*)(Variant *)>(VariantInternal::get_projection)); + case GDEXTENSION_VARIANT_TYPE_COLOR: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Color *(*)(Variant *)>(VariantInternal::get_color)); + case GDEXTENSION_VARIANT_TYPE_STRING_NAME: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<StringName *(*)(Variant *)>(VariantInternal::get_string_name)); + case GDEXTENSION_VARIANT_TYPE_NODE_PATH: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<NodePath *(*)(Variant *)>(VariantInternal::get_node_path)); + case GDEXTENSION_VARIANT_TYPE_RID: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<RID *(*)(Variant *)>(VariantInternal::get_rid)); + case GDEXTENSION_VARIANT_TYPE_OBJECT: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Object **(*)(Variant *)>(VariantInternal::get_object)); + case GDEXTENSION_VARIANT_TYPE_CALLABLE: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Callable *(*)(Variant *)>(VariantInternal::get_callable)); + case GDEXTENSION_VARIANT_TYPE_SIGNAL: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Signal *(*)(Variant *)>(VariantInternal::get_signal)); + case GDEXTENSION_VARIANT_TYPE_DICTIONARY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Dictionary *(*)(Variant *)>(VariantInternal::get_dictionary)); + case GDEXTENSION_VARIANT_TYPE_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<Array *(*)(Variant *)>(VariantInternal::get_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_BYTE_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedByteArray *(*)(Variant *)>(VariantInternal::get_byte_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_INT32_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedInt32Array *(*)(Variant *)>(VariantInternal::get_int32_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_INT64_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedInt64Array *(*)(Variant *)>(VariantInternal::get_int64_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT32_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedFloat32Array *(*)(Variant *)>(VariantInternal::get_float32_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT64_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedFloat64Array *(*)(Variant *)>(VariantInternal::get_float64_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_STRING_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedStringArray *(*)(Variant *)>(VariantInternal::get_string_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedVector2Array *(*)(Variant *)>(VariantInternal::get_vector2_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedVector3Array *(*)(Variant *)>(VariantInternal::get_vector3_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedColorArray *(*)(Variant *)>(VariantInternal::get_color_array)); + case GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY: + return reinterpret_cast<GDExtensionVariantGetInternalPtrFunc>(static_cast<PackedVector4Array *(*)(Variant *)>(VariantInternal::get_vector4_array)); + case GDEXTENSION_VARIANT_TYPE_NIL: + case GDEXTENSION_VARIANT_TYPE_VARIANT_MAX: + ERR_FAIL_V_MSG(nullptr, "Getting Variant get internal pointer function with invalid type."); + } + ERR_FAIL_V_MSG(nullptr, "Getting Variant get internal pointer function with invalid type."); +} + // ptrcalls static GDExtensionPtrOperatorEvaluator gdextension_variant_get_ptr_operator_evaluator(GDExtensionVariantOperator p_operator, GDExtensionVariantType p_type_a, GDExtensionVariantType p_type_b) { return (GDExtensionPtrOperatorEvaluator)Variant::get_ptr_operator_evaluator(Variant::Operator(p_operator), Variant::Type(p_type_a), Variant::Type(p_type_b)); @@ -1625,6 +1710,7 @@ void gdextension_setup_interface() { REGISTER_INTERFACE_FUNC(variant_can_convert_strict); REGISTER_INTERFACE_FUNC(get_variant_from_type_constructor); REGISTER_INTERFACE_FUNC(get_variant_to_type_constructor); + REGISTER_INTERFACE_FUNC(variant_get_ptr_internal_getter); REGISTER_INTERFACE_FUNC(variant_get_ptr_operator_evaluator); REGISTER_INTERFACE_FUNC(variant_get_ptr_builtin_method); REGISTER_INTERFACE_FUNC(variant_get_ptr_constructor); diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index 374dbfd071..8268afc3ad 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -198,6 +198,7 @@ typedef struct { typedef void (*GDExtensionVariantFromTypeConstructorFunc)(GDExtensionUninitializedVariantPtr, GDExtensionTypePtr); typedef void (*GDExtensionTypeFromVariantConstructorFunc)(GDExtensionUninitializedTypePtr, GDExtensionVariantPtr); +typedef void *(*GDExtensionVariantGetInternalPtrFunc)(GDExtensionVariantPtr); typedef void (*GDExtensionPtrOperatorEvaluator)(GDExtensionConstTypePtr p_left, GDExtensionConstTypePtr p_right, GDExtensionTypePtr r_result); typedef void (*GDExtensionPtrBuiltInMethod)(GDExtensionTypePtr p_base, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return, int p_argument_count); typedef void (*GDExtensionPtrConstructor)(GDExtensionUninitializedTypePtr p_base, const GDExtensionConstTypePtr *p_args); @@ -1384,6 +1385,23 @@ typedef GDExtensionVariantFromTypeConstructorFunc (*GDExtensionInterfaceGetVaria typedef GDExtensionTypeFromVariantConstructorFunc (*GDExtensionInterfaceGetVariantToTypeConstructor)(GDExtensionVariantType p_type); /** + * @name variant_get_ptr_internal_getter + * @since 4.4 + * + * Provides a function pointer for retrieving a pointer to a variant's internal value. + * Access to a variant's internal value can be used to modify it in-place, or to retrieve its value without the overhead of variant conversion functions. + * It is recommended to cache the getter for all variant types in a function table to avoid retrieval overhead upon use. + * + * @note Each function assumes the variant's type has already been determined and matches the function. + * Invoking the function with a variant of a mismatched type has undefined behavior, and may lead to a segmentation fault. + * + * @param p_type The Variant type. + * + * @return A pointer to a type-specific function that returns a pointer to the internal value of a variant. Check the implementation of this function (gdextension_variant_get_ptr_internal_getter) for pointee type info of each variant type. + */ +typedef GDExtensionVariantGetInternalPtrFunc (*GDExtensionInterfaceGetVariantGetInternalPtrFunc)(GDExtensionVariantType p_type); + +/** * @name variant_get_ptr_operator_evaluator * @since 4.1 * |