Merge pull request #949 from BastiaanOlij/fix_tests_refcounting
Change example code to properly test refcounted objectspull/892/head
commit
49a478a879
|
@ -28,7 +28,10 @@ func _ready():
|
||||||
($Example as Example).simple_const_func() # Force use of ptrcall
|
($Example as Example).simple_const_func() # Force use of ptrcall
|
||||||
prints(" returned", $Example.return_something("some string"))
|
prints(" returned", $Example.return_something("some string"))
|
||||||
prints(" returned const", $Example.return_something_const())
|
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(" returned ", $Example.get_v4())
|
||||||
|
|
||||||
prints("VarArg method calls")
|
prints("VarArg method calls")
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
[ext_resource type="Script" path="res://main.gd" id="1_c326s"]
|
[ext_resource type="Script" path="res://main.gd" id="1_c326s"]
|
||||||
|
|
||||||
[node name="Node" type="Node"]
|
[node name="Node" type="Node"]
|
||||||
script = ExtResource( "1_c326s" )
|
script = ExtResource("1_c326s")
|
||||||
|
|
||||||
[node name="Example" type="Example" parent="."]
|
[node name="Example" type="Example" parent="."]
|
||||||
|
|
||||||
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
||||||
|
layout_mode = 0
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Example"]
|
[node name="Label" type="Label" parent="Example"]
|
||||||
|
layout_mode = 0
|
||||||
offset_left = 194.0
|
offset_left = 194.0
|
||||||
offset_top = -2.0
|
offset_top = -2.0
|
||||||
offset_right = 234.0
|
offset_right = 234.0
|
||||||
|
|
|
@ -13,12 +13,27 @@
|
||||||
|
|
||||||
using namespace godot;
|
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() {
|
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() {
|
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) {
|
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("simple_const_func"), &Example::simple_const_func);
|
||||||
ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
|
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_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("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_array"), &Example::test_array);
|
||||||
ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg);
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<ExampleRef> Example::return_empty_ref() const {
|
||||||
|
Ref<ExampleRef> ref;
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
ExampleRef *Example::return_extended_ref() const {
|
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());
|
return memnew(ExampleRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
|
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<ExampleRef> ref;
|
||||||
ref.instantiate();
|
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());
|
UtilityFunctions::print(" Example ref checks called with value: ", p_ref->get_instance_id(), ", returning value: ", ref->get_instance_id());
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,20 @@ using namespace godot;
|
||||||
class ExampleRef : public RefCounted {
|
class ExampleRef : public RefCounted {
|
||||||
GDCLASS(ExampleRef, RefCounted);
|
GDCLASS(ExampleRef, RefCounted);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int instance_count;
|
||||||
|
static int last_id;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods() {}
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExampleRef();
|
ExampleRef();
|
||||||
~ExampleRef();
|
~ExampleRef();
|
||||||
|
|
||||||
|
int get_id();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExampleMin : public Control {
|
class ExampleMin : public Control {
|
||||||
|
@ -79,6 +87,7 @@ public:
|
||||||
void simple_const_func() const;
|
void simple_const_func() const;
|
||||||
String return_something(const String &base);
|
String return_something(const String &base);
|
||||||
Viewport *return_something_const() const;
|
Viewport *return_something_const() const;
|
||||||
|
Ref<ExampleRef> return_empty_ref() const;
|
||||||
ExampleRef *return_extended_ref() const;
|
ExampleRef *return_extended_ref() const;
|
||||||
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
|
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
|
||||||
Variant varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);
|
Variant varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);
|
||||||
|
|
Loading…
Reference in New Issue