Browse Source

Directly get object instance ID from `Variant` and implement `Variant::get_validated_object()`

David Snopek 10 months ago
parent
commit
0602c32986

+ 12 - 0
gdextension/gdextension_interface.h

@@ -1271,6 +1271,18 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVaria
  */
  */
 typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid);
 typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid);
 
 
+/**
+ * @name variant_get_object_instance_id
+ * @since 4.4
+ *
+ * Gets the object instance ID from a variant of type GDEXTENSION_VARIANT_TYPE_OBJECT.
+ *
+ * @param p_self A pointer to the Variant.
+ *
+ * @return The instance ID for the contained object.
+ */
+typedef GDObjectInstanceID (*GDExtensionInterfaceVariantGetObjectInstanceId)(GDExtensionConstVariantPtr p_self);
+
 /**
 /**
  * @name variant_get_type_name
  * @name variant_get_type_name
  * @since 4.1
  * @since 4.1

+ 1 - 0
include/godot_cpp/godot.hpp

@@ -82,6 +82,7 @@ extern "C" GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_
 extern "C" GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method;
 extern "C" GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method;
 extern "C" GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member;
 extern "C" GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member;
 extern "C" GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key;
 extern "C" GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key;
+extern "C" GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id;
 extern "C" GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name;
 extern "C" GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name;
 extern "C" GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert;
 extern "C" GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert;
 extern "C" GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict;
 extern "C" GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict;

+ 2 - 0
include/godot_cpp/variant/variant.hpp

@@ -264,6 +264,8 @@ public:
 	operator PackedColorArray() const;
 	operator PackedColorArray() const;
 	operator PackedVector4Array() const;
 	operator PackedVector4Array() const;
 
 
+	Object *get_validated_object() const;
+
 	Variant &operator=(const Variant &other);
 	Variant &operator=(const Variant &other);
 	Variant &operator=(Variant &&other);
 	Variant &operator=(Variant &&other);
 	bool operator==(const Variant &other) const;
 	bool operator==(const Variant &other) const;

+ 2 - 0
src/godot.cpp

@@ -88,6 +88,7 @@ GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type = null
 GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method = nullptr;
 GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method = nullptr;
 GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member = nullptr;
 GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member = nullptr;
 GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key = nullptr;
 GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key = nullptr;
+GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id = nullptr;
 GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name = nullptr;
 GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name = nullptr;
 GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert = nullptr;
 GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert = nullptr;
 GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict = nullptr;
 GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict = nullptr;
@@ -367,6 +368,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	LOAD_PROC_ADDRESS(variant_has_method, GDExtensionInterfaceVariantHasMethod);
 	LOAD_PROC_ADDRESS(variant_has_method, GDExtensionInterfaceVariantHasMethod);
 	LOAD_PROC_ADDRESS(variant_has_member, GDExtensionInterfaceVariantHasMember);
 	LOAD_PROC_ADDRESS(variant_has_member, GDExtensionInterfaceVariantHasMember);
 	LOAD_PROC_ADDRESS(variant_has_key, GDExtensionInterfaceVariantHasKey);
 	LOAD_PROC_ADDRESS(variant_has_key, GDExtensionInterfaceVariantHasKey);
+	LOAD_PROC_ADDRESS(variant_get_object_instance_id, GDExtensionInterfaceVariantGetObjectInstanceId);
 	LOAD_PROC_ADDRESS(variant_get_type_name, GDExtensionInterfaceVariantGetTypeName);
 	LOAD_PROC_ADDRESS(variant_get_type_name, GDExtensionInterfaceVariantGetTypeName);
 	LOAD_PROC_ADDRESS(variant_can_convert, GDExtensionInterfaceVariantCanConvert);
 	LOAD_PROC_ADDRESS(variant_can_convert, GDExtensionInterfaceVariantCanConvert);
 	LOAD_PROC_ADDRESS(variant_can_convert_strict, GDExtensionInterfaceVariantCanConvertStrict);
 	LOAD_PROC_ADDRESS(variant_can_convert_strict, GDExtensionInterfaceVariantCanConvertStrict);

+ 5 - 6
src/variant/variant.cpp

@@ -448,12 +448,7 @@ Variant::operator ObjectID() const {
 	if (get_type() == Type::INT) {
 	if (get_type() == Type::INT) {
 		return ObjectID(operator uint64_t());
 		return ObjectID(operator uint64_t());
 	} else if (get_type() == Type::OBJECT) {
 	} else if (get_type() == Type::OBJECT) {
-		Object *obj = operator Object *();
-		if (obj != nullptr) {
-			return ObjectID(obj->get_instance_id());
-		} else {
-			return ObjectID();
-		}
+		return ObjectID(internal::gdextension_interface_variant_get_object_instance_id(_native_ptr()));
 	} else {
 	} else {
 		return ObjectID();
 		return ObjectID();
 	}
 	}
@@ -515,6 +510,10 @@ Variant::operator PackedVector4Array() const {
 	return PackedVector4Array(this);
 	return PackedVector4Array(this);
 }
 }
 
 
+Object *Variant::get_validated_object() const {
+	return ObjectDB::get_instance(operator ObjectID());
+}
+
 Variant &Variant::operator=(const Variant &other) {
 Variant &Variant::operator=(const Variant &other) {
 	clear();
 	clear();
 	internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
 	internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());

+ 6 - 0
test/project/main.gd

@@ -206,6 +206,12 @@ func _ready():
 	assert_equal(example.test_variant_float_conversion(10.0), 10.0)
 	assert_equal(example.test_variant_float_conversion(10.0), 10.0)
 	assert_equal(example.test_variant_float_conversion(10), 10.0)
 	assert_equal(example.test_variant_float_conversion(10), 10.0)
 
 
+	# Test checking if objects are valid.
+	var object_of_questionable_validity = Object.new()
+	assert_equal(example.test_object_is_valid(object_of_questionable_validity), true)
+	object_of_questionable_validity.free()
+	assert_equal(example.test_object_is_valid(object_of_questionable_validity), false)
+
 	# Test that ptrcalls from GDExtension to the engine are correctly encoding Object and RefCounted.
 	# Test that ptrcalls from GDExtension to the engine are correctly encoding Object and RefCounted.
 	var new_node = Node.new()
 	var new_node = Node.new()
 	example.test_add_child(new_node)
 	example.test_add_child(new_node)

+ 5 - 0
test/src/example.cpp

@@ -215,6 +215,7 @@ void Example::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("test_variant_vector2i_conversion", "variant"), &Example::test_variant_vector2i_conversion);
 	ClassDB::bind_method(D_METHOD("test_variant_vector2i_conversion", "variant"), &Example::test_variant_vector2i_conversion);
 	ClassDB::bind_method(D_METHOD("test_variant_int_conversion", "variant"), &Example::test_variant_int_conversion);
 	ClassDB::bind_method(D_METHOD("test_variant_int_conversion", "variant"), &Example::test_variant_int_conversion);
 	ClassDB::bind_method(D_METHOD("test_variant_float_conversion", "variant"), &Example::test_variant_float_conversion);
 	ClassDB::bind_method(D_METHOD("test_variant_float_conversion", "variant"), &Example::test_variant_float_conversion);
+	ClassDB::bind_method(D_METHOD("test_object_is_valid", "variant"), &Example::test_object_is_valid);
 
 
 	ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
 	ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
 	ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
 	ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
@@ -579,6 +580,10 @@ float Example::test_variant_float_conversion(const Variant &p_variant) const {
 	return p_variant;
 	return p_variant;
 }
 }
 
 
+bool Example::test_object_is_valid(const Variant &p_variant) const {
+	return static_cast<bool>(p_variant.get_validated_object());
+}
+
 void Example::test_add_child(Node *p_node) {
 void Example::test_add_child(Node *p_node) {
 	add_child(p_node);
 	add_child(p_node);
 }
 }

+ 1 - 0
test/src/example.h

@@ -145,6 +145,7 @@ public:
 	Vector2i test_variant_vector2i_conversion(const Variant &p_variant) const;
 	Vector2i test_variant_vector2i_conversion(const Variant &p_variant) const;
 	int test_variant_int_conversion(const Variant &p_variant) const;
 	int test_variant_int_conversion(const Variant &p_variant) const;
 	float test_variant_float_conversion(const Variant &p_variant) const;
 	float test_variant_float_conversion(const Variant &p_variant) const;
+	bool test_object_is_valid(const Variant &p_variant) const;
 
 
 	void test_add_child(Node *p_node);
 	void test_add_child(Node *p_node);
 	void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;
 	void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;