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.pull/989/head
parent
129c358a72
commit
9fd33b5cde
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue