瀏覽代碼

Change example code to properly represent test cases with refcounted objects

Bastiaan Olij 2 年之前
父節點
當前提交
f24ee56c5d
共有 4 個文件被更改,包括 46 次插入8 次删除
  1. 4 1
      test/demo/main.gd
  2. 3 1
      test/demo/main.tscn
  3. 29 5
      test/src/example.cpp
  4. 10 1
      test/src/example.h

+ 4 - 1
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")

+ 3 - 1
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

+ 29 - 5
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;
 }

+ 10 - 1
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);