summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastiaan Olij <mux213@gmail.com>2022-12-05 22:04:08 +1100
committerBastiaan Olij <mux213@gmail.com>2022-12-05 22:28:28 +1100
commitf24ee56c5db57585a8d6bba593c5fbf49f5e99a8 (patch)
tree198a970bd78f03f68a024a447a15c1dbe47ab41f
parent32859ea25c31ae596535d6bf0178a6e01f45a001 (diff)
downloadredot-cpp-f24ee56c5db57585a8d6bba593c5fbf49f5e99a8.tar.gz
Change example code to properly represent test cases with refcounted objects
-rw-r--r--test/demo/main.gd5
-rw-r--r--test/demo/main.tscn4
-rw-r--r--test/src/example.cpp34
-rw-r--r--test/src/example.h11
4 files changed, 46 insertions, 8 deletions
diff --git a/test/demo/main.gd b/test/demo/main.gd
index 7d36ef1..a3a4be2 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 b2a1eae..ab1b91e 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 3e10f32..ad2c844 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<ExampleRef> Example::return_empty_ref() const {
+ Ref<ExampleRef> 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<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
+ // This is therefor the prefered way of instancing and returning a refcounted object:
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;
}
diff --git a/test/src/example.h b/test/src/example.h
index 44c1531..8332ed4 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<ExampleRef> return_empty_ref() 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);