From ad726015e7bb5aaaf6d8f3b98fca2b21bf15c830 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Tue, 23 May 2023 15:17:06 -0500 Subject: [PATCH] Revert the changes from PR #1044 and #1045 and standardize on `Object **` encoding in ptrcall --- binding_generator.py | 2 +- include/godot_cpp/classes/ref.hpp | 7 +- include/godot_cpp/core/method_ptrcall.hpp | 4 +- test/project/main.gd | 93 +++++++++++++---------- test/project/main.tscn | 4 +- test/project/project.godot | 2 +- test/src/example.cpp | 7 ++ test/src/example.h | 2 + 8 files changed, 70 insertions(+), 51 deletions(-) diff --git a/binding_generator.py b/binding_generator.py index fef36d3a..42307c8d 100644 --- a/binding_generator.py +++ b/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}" diff --git a/include/godot_cpp/classes/ref.hpp b/include/godot_cpp/classes/ref.hpp index b80227d9..92a1e7f7 100644 --- a/include/godot_cpp/classes/ref.hpp +++ b/include/godot_cpp/classes/ref.hpp @@ -229,9 +229,9 @@ public: template struct PtrToArg> { _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - // Important: p_ptr is T*, not Ref*, since Object* is what engine gives to ptrcall. + GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr; ERR_FAIL_NULL_V(p_ptr, Ref()); - return Ref(reinterpret_cast(godot::internal::get_object_instance_binding(reinterpret_cast(const_cast(p_ptr))))); + return Ref(reinterpret_cast(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref)))); } typedef Ref EncodeT; @@ -253,8 +253,9 @@ struct PtrToArg &> { typedef Ref EncodeT; _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + GDExtensionRefPtr ref = const_cast(p_ptr); ERR_FAIL_NULL_V(p_ptr, Ref()); - return Ref(reinterpret_cast(godot::internal::get_object_instance_binding(reinterpret_cast(const_cast(p_ptr))))); + return Ref(reinterpret_cast(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref)))); } }; diff --git a/include/godot_cpp/core/method_ptrcall.hpp b/include/godot_cpp/core/method_ptrcall.hpp index 283f4b04..a85cbc94 100644 --- a/include/godot_cpp/core/method_ptrcall.hpp +++ b/include/godot_cpp/core/method_ptrcall.hpp @@ -169,7 +169,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant); template struct PtrToArg { _FORCE_INLINE_ static T *convert(const void *p_ptr) { - return reinterpret_cast(godot::internal::get_object_instance_binding(reinterpret_cast(const_cast(p_ptr)))); + return reinterpret_cast(godot::internal::get_object_instance_binding(*reinterpret_cast(const_cast(p_ptr)))); } typedef Object *EncodeT; _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { @@ -180,7 +180,7 @@ struct PtrToArg { template struct PtrToArg { _FORCE_INLINE_ static const T *convert(const void *p_ptr) { - return reinterpret_cast(godot::internal::get_object_instance_binding(reinterpret_cast(const_cast(p_ptr)))); + return reinterpret_cast(godot::internal::get_object_instance_binding(*reinterpret_cast(const_cast(p_ptr)))); } typedef const Object *EncodeT; _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { diff --git a/test/project/main.gd b/test/project/main.gd index 7c141cf5..5abe864b 100644 --- a/test/project/main.gd +++ b/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() diff --git a/test/project/main.tscn b/test/project/main.tscn index ab1b91e5..2b98e0f0 100644 --- a/test/project/main.tscn +++ b/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="."] diff --git a/test/project/project.godot b/test/project/project.godot index cd174d2f..eafcad30 100644 --- a/test/project/project.godot +++ b/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] diff --git a/test/src/example.cpp b/test/src/example.cpp index 6d243798..e605a454 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -348,3 +348,10 @@ bool Example::_has_point(const Vector2 &point) const { return false; } + +void Example::_input(const Ref &event) { + const InputEventKey *key_event = Object::cast_to(*event); + if (key_event) { + emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode()); + } +} diff --git a/test/src/example.h b/test/src/example.h index ebf91560..8c8b2508 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -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 &event) override; }; VARIANT_ENUM_CAST(Example::Constants);