Browse Source

Merge pull request #989 from Faless/ext/4.x_objects_bind

Allow method binds to take Object subclasses as arguments
Fabio Alessandrelli 2 years ago
parent
commit
8ee9cab8f8
4 changed files with 26 additions and 3 deletions
  1. 18 3
      include/godot_cpp/core/binder_common.hpp
  2. 1 0
      test/demo/main.gd
  3. 6 0
      test/src/example.cpp
  4. 1 0
      test/src/example.h

+ 18 - 3
include/godot_cpp/core/binder_common.hpp

@@ -86,21 +86,36 @@ namespace godot {
 template <class T>
 template <class T>
 struct VariantCaster {
 struct VariantCaster {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
+		using TStripped = std::remove_pointer_t<T>;
+		if constexpr (std::is_base_of<Object, TStripped>::value) {
+			return Object::cast_to<TStripped>(p_variant);
+		} else {
+			return p_variant;
+		}
 	}
 	}
 };
 };
 
 
 template <class T>
 template <class T>
 struct VariantCaster<T &> {
 struct VariantCaster<T &> {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
+		using TStripped = std::remove_pointer_t<T>;
+		if constexpr (std::is_base_of<Object, TStripped>::value) {
+			return Object::cast_to<TStripped>(p_variant);
+		} else {
+			return p_variant;
+		}
 	}
 	}
 };
 };
 
 
 template <class T>
 template <class T>
 struct VariantCaster<const T &> {
 struct VariantCaster<const T &> {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
 	static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-		return p_variant;
+		using TStripped = std::remove_pointer_t<T>;
+		if constexpr (std::is_base_of<Object, TStripped>::value) {
+			return Object::cast_to<TStripped>(p_variant);
+		} else {
+			return p_variant;
+		}
 	}
 	}
 };
 };
 
 

+ 1 - 0
test/demo/main.gd

@@ -33,6 +33,7 @@ func _ready():
 	var ret_ref = $Example.return_extended_ref()
 	var ret_ref = $Example.return_extended_ref()
 	prints("  returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id())
 	prints("  returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id())
 	prints("  returned ", $Example.get_v4())
 	prints("  returned ", $Example.get_v4())
+	prints("  test node argument", $Example.test_node_argument($Example))
 
 
 	prints("VarArg method calls")
 	prints("VarArg method calls")
 	var ref = ExampleRef.new()
 	var ref = ExampleRef.new()

+ 6 - 0
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_arg", "array"), &Example::test_tarray_arg);
 	ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray);
 	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_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));
 	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());
 	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<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
 Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
 	// This is therefor the prefered way of instancing and returning a refcounted object:
 	// This is therefor the prefered way of instancing and returning a refcounted object:
 	Ref<ExampleRef> ref;
 	Ref<ExampleRef> ref;

+ 1 - 0
test/src/example.h

@@ -100,6 +100,7 @@ public:
 	void test_tarray_arg(const TypedArray<int64_t> &p_array);
 	void test_tarray_arg(const TypedArray<int64_t> &p_array);
 	TypedArray<Vector2> test_tarray() const;
 	TypedArray<Vector2> test_tarray() const;
 	Dictionary test_dictionary() const;
 	Dictionary test_dictionary() const;
+	Example *test_node_argument(Example *p_node) const;
 
 
 	// Property.
 	// Property.
 	void set_custom_position(const Vector2 &pos);
 	void set_custom_position(const Vector2 &pos);