From 9fd33b5cdedd214f6defc89049f520770e164260 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 10 Jan 2023 11:48:21 +0100 Subject: [PATCH] Allow method binds to take Object subclasses as arguments As done in upstream Godot via GH-57205. Add a test that ensures it works also for "gdextended" objects. --- include/godot_cpp/core/binder_common.hpp | 21 ++++++++++++++++++--- test/demo/main.gd | 1 + test/src/example.cpp | 6 ++++++ test/src/example.h | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/include/godot_cpp/core/binder_common.hpp b/include/godot_cpp/core/binder_common.hpp index 642c5ba0..207d3c1e 100644 --- a/include/godot_cpp/core/binder_common.hpp +++ b/include/godot_cpp/core/binder_common.hpp @@ -86,21 +86,36 @@ namespace godot { template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; diff --git a/test/demo/main.gd b/test/demo/main.gd index a3a4be20..5238753a 100644 --- a/test/demo/main.gd +++ b/test/demo/main.gd @@ -33,6 +33,7 @@ func _ready(): var ret_ref = $Example.return_extended_ref() prints(" returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id()) prints(" returned ", $Example.get_v4()) + prints(" test node argument", $Example.test_node_argument($Example)) prints("VarArg method calls") var ref = ExampleRef.new() diff --git a/test/src/example.cpp b/test/src/example.cpp index 2697e453..6da1f528 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -122,6 +122,7 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg); ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray); ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary); + ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument); ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200)); @@ -212,6 +213,11 @@ ExampleRef *Example::return_extended_ref() const { return memnew(ExampleRef()); } +Example *Example::test_node_argument(Example *p_node) const { + UtilityFunctions::print(" Test node argument called with ", p_node ? String::num(p_node->get_instance_id()) : "null"); + return p_node; +} + Ref Example::extended_ref_checks(Ref p_ref) const { // This is therefor the prefered way of instancing and returning a refcounted object: Ref ref; diff --git a/test/src/example.h b/test/src/example.h index c181f0d8..6857be2e 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -100,6 +100,7 @@ public: void test_tarray_arg(const TypedArray &p_array); TypedArray test_tarray() const; Dictionary test_dictionary() const; + Example *test_node_argument(Example *p_node) const; // Property. void set_custom_position(const Vector2 &pos);