From b90d0ac555035c4db9ebc2a3516acff72e5cfb43 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 28 Sep 2021 15:49:08 +0200 Subject: [PATCH 1/2] Add Ref binding support. Added PtrToArg and GetTypeInfo adapted from Godot. --- include/godot_cpp/classes/ref.hpp | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/godot_cpp/classes/ref.hpp b/include/godot_cpp/classes/ref.hpp index b5fec34..71c8d88 100644 --- a/include/godot_cpp/classes/ref.hpp +++ b/include/godot_cpp/classes/ref.hpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -236,6 +237,48 @@ public: } }; +template +struct PtrToArg> { + _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + return Ref(godot::internal::interface->object_get_instance_binding((void *)p_ptr, godot::internal::token, &T::___binding_callbacks)); + } + + typedef Ref EncodeT; + + _FORCE_INLINE_ static void encode(Ref p_val, const void *p_ptr) { + *(void **)p_ptr = p_val->_owner; + } +}; + +template +struct PtrToArg &> { + typedef Ref EncodeT; + + _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + return Ref(godot::internal::interface->object_get_instance_binding((void *)p_ptr, godot::internal::token, &T::___binding_callbacks)); + } +}; + +template +struct GetTypeInfo, typename EnableIf::value>::type> { + static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + + static inline PropertyInfo get_class_info() { + return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + } +}; + +template +struct GetTypeInfo &, typename EnableIf::value>::type> { + static const GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_OBJECT; + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + + static inline PropertyInfo get_class_info() { + return PropertyInfo(GDNATIVE_VARIANT_TYPE_OBJECT, T::get_class_static()); + } +}; + } // namespace godot #endif // ! GODOT_CPP_REF_HPP From b28853aff1a917c3a9ad47915856ea0fd2373254 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 28 Sep 2021 15:49:53 +0200 Subject: [PATCH 2/2] Add test for Reference passing/returning. --- test/demo/main.gd | 2 ++ test/src/example.cpp | 10 ++++++++++ test/src/example.h | 1 + 3 files changed, 13 insertions(+) diff --git a/test/demo/main.gd b/test/demo/main.gd index 557e901..f519c09 100644 --- a/test/demo/main.gd +++ b/test/demo/main.gd @@ -10,6 +10,8 @@ func _ready(): prints("returned", $Example.return_something("some string")) prints("returned const", $Example.return_something_const()) prints("returned ref", $Example.return_extended_ref()) + var ref = ExampleRef.new() + prints("sending ref: ", ref.get_instance_id(), "returned ref: ", $Example.extended_ref_checks(ref).get_instance_id()) prints("vararg args", $Example.varargs_func("some", "arguments", "to", "test")) # Use properties. diff --git a/test/src/example.cpp b/test/src/example.cpp index e3ed316..4d34d4c 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -53,6 +53,7 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something); ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const); ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref); + ClassDB::bind_method(D_METHOD("extended_ref_checks"), &Example::extended_ref_checks); { MethodInfo mi; @@ -107,6 +108,15 @@ ExampleRef *Example::return_extended_ref() const { return memnew(ExampleRef()); } +Ref Example::extended_ref_checks(Ref p_ref) const { + Ref ref; + ref.instantiate(); + // TODO the returned value gets dereferenced too early and return a null object otherwise. + ref->reference(); + UtilityFunctions::print("Example ref checks called with value: ", p_ref->get_instance_id(), ", returning value: ", ref->get_instance_id()); + return ref; +} + Variant Example::varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error) { UtilityFunctions::print("Varargs called with ", String::num(arg_count), " arguments"); return arg_count; diff --git a/test/src/example.h b/test/src/example.h index e72051b..c72ad60 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -76,6 +76,7 @@ public: String return_something(const String &base); Viewport *return_something_const() const; ExampleRef *return_extended_ref() const; + Ref extended_ref_checks(Ref p_ref) const; Variant varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error); void emit_custom_signal(const String &name, int value);