Explorar el Código

Merge pull request #631 from Faless/ext/ref_casting_2

Rémi Verschelde hace 3 años
padre
commit
6a720e5c7c
Se han modificado 4 ficheros con 56 adiciones y 0 borrados
  1. 43 0
      include/godot_cpp/classes/ref.hpp
  2. 2 0
      test/demo/main.gd
  3. 10 0
      test/src/example.cpp
  4. 1 0
      test/src/example.h

+ 43 - 0
include/godot_cpp/classes/ref.hpp

@@ -35,6 +35,7 @@
 
 #include <godot_cpp/classes/object.hpp>
 #include <godot_cpp/classes/ref_counted.hpp>
+#include <godot_cpp/core/binder_common.hpp>
 #include <godot_cpp/core/memory.hpp>
 #include <godot_cpp/variant/variant.hpp>
 
@@ -236,6 +237,48 @@ public:
 	}
 };
 
+template <class T>
+struct PtrToArg<Ref<T>> {
+	_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
+		return Ref<T>(godot::internal::interface->object_get_instance_binding((void *)p_ptr, godot::internal::token, &T::___binding_callbacks));
+	}
+
+	typedef Ref<T> EncodeT;
+
+	_FORCE_INLINE_ static void encode(Ref<T> p_val, const void *p_ptr) {
+		*(void **)p_ptr = p_val->_owner;
+	}
+};
+
+template <class T>
+struct PtrToArg<const Ref<T> &> {
+	typedef Ref<T> EncodeT;
+
+	_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
+		return Ref<T>(godot::internal::interface->object_get_instance_binding((void *)p_ptr, godot::internal::token, &T::___binding_callbacks));
+	}
+};
+
+template <class T>
+struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::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 <class T>
+struct GetTypeInfo<const Ref<T> &, typename EnableIf<TypeInherits<RefCounted, T>::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

+ 2 - 0
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.

+ 10 - 0
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<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
+	Ref<ExampleRef> 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;

+ 1 - 0
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<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
 	Variant varargs_func(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error);
 	void emit_custom_signal(const String &name, int value);