diff --git a/test/demo/main.gd b/test/demo/main.gd index 7d36ef1f..a3a4be20 100644 --- a/test/demo/main.gd +++ b/test/demo/main.gd @@ -28,7 +28,10 @@ func _ready(): ($Example as Example).simple_const_func() # Force use of ptrcall prints(" returned", $Example.return_something("some string")) prints(" returned const", $Example.return_something_const()) - prints(" returned ref", $Example.return_extended_ref()) + var null_ref = $Example.return_empty_ref() + prints(" returned empty ref", null_ref) + var ret_ref = $Example.return_extended_ref() + prints(" returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id()) prints(" returned ", $Example.get_v4()) prints("VarArg method calls") diff --git a/test/demo/main.tscn b/test/demo/main.tscn index b2a1eaea..ab1b91e5 100644 --- a/test/demo/main.tscn +++ b/test/demo/main.tscn @@ -3,13 +3,15 @@ [ext_resource type="Script" path="res://main.gd" id="1_c326s"] [node name="Node" type="Node"] -script = ExtResource( "1_c326s" ) +script = ExtResource("1_c326s") [node name="Example" type="Example" parent="."] [node name="ExampleMin" type="ExampleMin" parent="Example"] +layout_mode = 0 [node name="Label" type="Label" parent="Example"] +layout_mode = 0 offset_left = 194.0 offset_top = -2.0 offset_right = 234.0 diff --git a/test/src/example.cpp b/test/src/example.cpp index 224b8036..2697e453 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -13,12 +13,27 @@ using namespace godot; +int ExampleRef::instance_count = 0; +int ExampleRef::last_id = 0; + +int ExampleRef::get_id() { + return id; +} + +void ExampleRef::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id); +} + ExampleRef::ExampleRef() { - UtilityFunctions::print("ExampleRef created."); + id = ++last_id; + instance_count++; + + UtilityFunctions::print("ExampleRef ", itos(id), " created, current instance count: ", itos(instance_count)); } ExampleRef::~ExampleRef() { - UtilityFunctions::print("ExampleRef destroyed."); + instance_count--; + UtilityFunctions::print("ExampleRef ", itos(id), " destroyed, current instance count: ", itos(instance_count)); } int Example::test_static(int p_a, int p_b) { @@ -99,8 +114,9 @@ void Example::_bind_methods() { ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func); 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_empty_ref"), &Example::return_empty_ref); ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref); - ClassDB::bind_method(D_METHOD("extended_ref_checks"), &Example::extended_ref_checks); + ClassDB::bind_method(D_METHOD("extended_ref_checks", "ref"), &Example::extended_ref_checks); ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array); ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg); @@ -184,15 +200,23 @@ Viewport *Example::return_something_const() const { return nullptr; } +Ref Example::return_empty_ref() const { + Ref ref; + return ref; +} + ExampleRef *Example::return_extended_ref() const { + // You can instance and return a refcounted object like this, but keep in mind that refcounting starts with the returned object + // and it will be destroyed when all references are destroyed. If you store this pointer you run the risk of having a pointer + // to a destroyed object. return memnew(ExampleRef()); } Ref Example::extended_ref_checks(Ref p_ref) const { + // This is therefor the prefered way of instancing and returning a refcounted object: Ref 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; } diff --git a/test/src/example.h b/test/src/example.h index e354e4f5..c181f0d8 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -25,12 +25,20 @@ using namespace godot; class ExampleRef : public RefCounted { GDCLASS(ExampleRef, RefCounted); +private: + static int instance_count; + static int last_id; + + int id; + protected: - static void _bind_methods() {} + static void _bind_methods(); public: ExampleRef(); ~ExampleRef(); + + int get_id(); }; class ExampleMin : public Control { @@ -79,6 +87,7 @@ public: void simple_const_func() const; String return_something(const String &base); Viewport *return_something_const() const; + Ref return_empty_ref() const; ExampleRef *return_extended_ref() const; Ref extended_ref_checks(Ref p_ref) const; Variant varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);