浏览代码

Revert the changes from PR #1044 and #1045 and standardize on `Object **` encoding in ptrcall

David Snopek 2 年之前
父节点
当前提交
ad726015e7

+ 1 - 1
binding_generator.py

@@ -1887,7 +1887,7 @@ def get_encoded_arg(arg_name, type_name, type_meta):
     elif is_engine_class(type_name):
         # `{name}` is a C++ wrapper, it contains a field which is the object's pointer Godot expects.
         # We have to check `nullptr` because when the caller sends `nullptr`, the wrapper itself will be null.
-        name = f"({name} != nullptr ? {name}->_owner : nullptr)"
+        name = f"({name} != nullptr ? &{name}->_owner : nullptr)"
     else:
         name = f"&{name}"
 

+ 4 - 3
include/godot_cpp/classes/ref.hpp

@@ -229,9 +229,9 @@ public:
 template <class T>
 struct PtrToArg<Ref<T>> {
 	_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
-		// Important: p_ptr is T*, not Ref<T>*, since Object* is what engine gives to ptrcall.
+		GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
 		ERR_FAIL_NULL_V(p_ptr, Ref<T>());
-		return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(reinterpret_cast<GDExtensionObjectPtr>(const_cast<void *>(p_ptr)))));
+		return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
 	}
 
 	typedef Ref<T> EncodeT;
@@ -253,8 +253,9 @@ struct PtrToArg<const Ref<T> &> {
 	typedef Ref<T> EncodeT;
 
 	_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
+		GDExtensionRefPtr ref = const_cast<GDExtensionRefPtr>(p_ptr);
 		ERR_FAIL_NULL_V(p_ptr, Ref<T>());
-		return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(reinterpret_cast<GDExtensionObjectPtr>(const_cast<void *>(p_ptr)))));
+		return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
 	}
 };
 

+ 2 - 2
include/godot_cpp/core/method_ptrcall.hpp

@@ -169,7 +169,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
 template <class T>
 struct PtrToArg<T *> {
 	_FORCE_INLINE_ static T *convert(const void *p_ptr) {
-		return reinterpret_cast<T *>(godot::internal::get_object_instance_binding(reinterpret_cast<GDExtensionObjectPtr>(const_cast<void *>(p_ptr))));
+		return reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
 	}
 	typedef Object *EncodeT;
 	_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
@@ -180,7 +180,7 @@ struct PtrToArg<T *> {
 template <class T>
 struct PtrToArg<const T *> {
 	_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
-		return reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(reinterpret_cast<GDExtensionObjectPtr>(const_cast<void *>(p_ptr))));
+		return reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
 	}
 	typedef const Object *EncodeT;
 	_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {

+ 51 - 42
test/project/main.gd

@@ -4,97 +4,106 @@ var custom_signal_emitted = null
 
 
 func _ready():
+	var example: Example = $Example
+
 	# Signal.
-	$Example.emit_custom_signal("Button", 42)
+	example.emit_custom_signal("Button", 42)
 	assert_equal(custom_signal_emitted, ["Button", 42])
 
 	# To string.
-	assert_equal($Example.to_string(),'Example:[ GDExtension::Example <--> Instance ID:%s ]' % $Example.get_instance_id())
+	assert_equal(example.to_string(),'Example:[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
 	# It appears there's a bug with instance ids :-(
 	#assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:[Wrapped:%s]' % $Example/ExampleMin.get_instance_id())
 
 	# Call static methods.
-	assert_equal($Example.test_static(9, 100), 109);
+	assert_equal(Example.test_static(9, 100), 109);
 	# It's void and static, so all we know is that it didn't crash.
-	$Example.test_static2()
+	Example.test_static2()
 
 	# Property list.
-	$Example.property_from_list = Vector3(100, 200, 300)
-	assert_equal($Example.property_from_list, Vector3(100, 200, 300))
+	example.property_from_list = Vector3(100, 200, 300)
+	assert_equal(example.property_from_list, Vector3(100, 200, 300))
 
 	# Call simple methods.
-	$Example.simple_func()
+	example.simple_func()
 	assert_equal(custom_signal_emitted, ['simple_func', 3])
-	($Example as Example).simple_const_func() # Force use of ptrcall
+	example.simple_const_func()
 	assert_equal(custom_signal_emitted, ['simple_const_func', 4])
 
 	# Pass custom reference.
-	assert_equal($Example.custom_ref_func(null), -1)
+	assert_equal(example.custom_ref_func(null), -1)
 	var ref1 = ExampleRef.new()
 	ref1.id = 27
-	assert_equal($Example.custom_ref_func(ref1), 27)
+	assert_equal(example.custom_ref_func(ref1), 27)
 	ref1.id += 1;
-	assert_equal($Example.custom_const_ref_func(ref1), 28)
+	assert_equal(example.custom_const_ref_func(ref1), 28)
 
 	# Pass core reference.
-	assert_equal($Example.image_ref_func(null), "invalid")
-	assert_equal($Example.image_const_ref_func(null), "invalid")
+	assert_equal(example.image_ref_func(null), "invalid")
+	assert_equal(example.image_const_ref_func(null), "invalid")
 	var image = Image.new()
-	assert_equal($Example.image_ref_func(image), "valid")
-	assert_equal($Example.image_const_ref_func(image), "valid")
+	assert_equal(example.image_ref_func(image), "valid")
+	assert_equal(example.image_const_ref_func(image), "valid")
 
 	# Return values.
-	assert_equal($Example.return_something("some string"), "some string42")
-	assert_equal($Example.return_something_const(), get_viewport())
-	var null_ref = $Example.return_empty_ref()
+	assert_equal(example.return_something("some string"), "some string42")
+	assert_equal(example.return_something_const(), get_viewport())
+	var null_ref = example.return_empty_ref()
 	assert_equal(null_ref, null)
-	var ret_ref = $Example.return_extended_ref()
+	var ret_ref = example.return_extended_ref()
 	assert_not_equal(ret_ref.get_instance_id(), 0)
 	assert_equal(ret_ref.get_id(), 0)
-	assert_equal($Example.get_v4(), Vector4(1.2, 3.4, 5.6, 7.8))
-	assert_equal($Example.test_node_argument($Example), $Example)
+	assert_equal(example.get_v4(), Vector4(1.2, 3.4, 5.6, 7.8))
+	assert_equal(example.test_node_argument(example), example)
 
 	# VarArg method calls.
 	var var_ref = ExampleRef.new()
-	assert_not_equal($Example.extended_ref_checks(var_ref).get_instance_id(), var_ref.get_instance_id())
-	assert_equal($Example.varargs_func("some", "arguments", "to", "test"), 4)
-	assert_equal($Example.varargs_func_nv("some", "arguments", "to", "test"), 46)
-	$Example.varargs_func_void("some", "arguments", "to", "test")
+	assert_not_equal(example.extended_ref_checks(var_ref).get_instance_id(), var_ref.get_instance_id())
+	assert_equal(example.varargs_func("some", "arguments", "to", "test"), 4)
+	assert_equal(example.varargs_func_nv("some", "arguments", "to", "test"), 46)
+	example.varargs_func_void("some", "arguments", "to", "test")
 	assert_equal(custom_signal_emitted, ["varargs_func_void", 5])
 
 	# Method calls with default values.
-	assert_equal($Example.def_args(), 300)
-	assert_equal($Example.def_args(50), 250)
-	assert_equal($Example.def_args(50, 100), 150)
+	assert_equal(example.def_args(), 300)
+	assert_equal(example.def_args(50), 250)
+	assert_equal(example.def_args(50, 100), 150)
 
 	# Array and Dictionary
-	assert_equal($Example.test_array(), [1, 2])
-	assert_equal($Example.test_tarray(), [ Vector2(1, 2), Vector2(2, 3) ])
-	assert_equal($Example.test_dictionary(), {"hello": "world", "foo": "bar"})
+	assert_equal(example.test_array(), [1, 2])
+	assert_equal(example.test_tarray(), [ Vector2(1, 2), Vector2(2, 3) ])
+	assert_equal(example.test_dictionary(), {"hello": "world", "foo": "bar"})
 	var array: Array[int] = [1, 2, 3]
-	assert_equal($Example.test_tarray_arg(array), 6)
+	assert_equal(example.test_tarray_arg(array), 6)
 
 	# String += operator
-	assert_equal($Example.test_string_ops(), "ABCĎE")
+	assert_equal(example.test_string_ops(), "ABCĎE")
 
 	# PackedArray iterators
-	assert_equal($Example.test_vector_ops(), 105)
+	assert_equal(example.test_vector_ops(), 105)
 
 	# Properties.
-	assert_equal($Example.group_subgroup_custom_position, Vector2(0, 0))
-	$Example.group_subgroup_custom_position = Vector2(50, 50)
-	assert_equal($Example.group_subgroup_custom_position, Vector2(50, 50))
+	assert_equal(example.group_subgroup_custom_position, Vector2(0, 0))
+	example.group_subgroup_custom_position = Vector2(50, 50)
+	assert_equal(example.group_subgroup_custom_position, Vector2(50, 50))
 
 	# Constants.
-	assert_equal($Example.FIRST, 0)
-	assert_equal($Example.ANSWER_TO_EVERYTHING, 42)
-	assert_equal($Example.CONSTANT_WITHOUT_ENUM, 314)
+	assert_equal(Example.FIRST, 0)
+	assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
+	assert_equal(Example.CONSTANT_WITHOUT_ENUM, 314)
 
 	# BitFields.
 	assert_equal(Example.FLAG_ONE, 1)
 	assert_equal(Example.FLAG_TWO, 2)
-	assert_equal($Example.test_bitfield(0), 0)
-	assert_equal($Example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
+	assert_equal(example.test_bitfield(0), 0)
+	assert_equal(example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
+
+	# Virtual method.
+	var event = InputEventKey.new()
+	event.key_label = KEY_H
+	event.unicode = 72
+	get_viewport().push_input(event)
+	assert_equal(custom_signal_emitted, ["_input: H", 72])
 
 	exit_with_status()
 

+ 2 - 2
test/project/main.tscn

@@ -1,9 +1,9 @@
 [gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
 
-[ext_resource type="Script" path="res://main.gd" id="1_c326s"]
+[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
 
 [node name="Node" type="Node"]
-script = ExtResource("1_c326s")
+script = ExtResource("1_qesh5")
 
 [node name="Example" type="Example" parent="."]
 

+ 1 - 1
test/project/project.godot

@@ -12,7 +12,7 @@ config_version=5
 
 config/name="GDExtension Test Project"
 run/main_scene="res://main.tscn"
-config/features=PackedStringArray("4.0")
+config/features=PackedStringArray("4.1")
 config/icon="res://icon.png"
 
 [native_extensions]

+ 7 - 0
test/src/example.cpp

@@ -348,3 +348,10 @@ bool Example::_has_point(const Vector2 &point) const {
 
 	return false;
 }
+
+void Example::_input(const Ref<InputEvent> &event) {
+	const InputEventKey *key_event = Object::cast_to<const InputEventKey>(*event);
+	if (key_event) {
+		emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
+	}
+}

+ 2 - 0
test/src/example.h

@@ -17,6 +17,7 @@
 #include <godot_cpp/classes/control.hpp>
 #include <godot_cpp/classes/global_constants.hpp>
 #include <godot_cpp/classes/image.hpp>
+#include <godot_cpp/classes/input_event_key.hpp>
 #include <godot_cpp/classes/viewport.hpp>
 
 #include <godot_cpp/core/binder_common.hpp>
@@ -129,6 +130,7 @@ public:
 
 	// Virtual function override (no need to bind manually).
 	virtual bool _has_point(const Vector2 &point) const override;
+	virtual void _input(const Ref<InputEvent> &event) override;
 };
 
 VARIANT_ENUM_CAST(Example::Constants);