Correctly handle `Object *` arguments that were encoded as `nullptr`

pull/1405/head
David Snopek 2024-03-05 11:11:29 -06:00
parent e55b792fea
commit 37542dc2ec
2 changed files with 8 additions and 4 deletions

View File

@ -170,11 +170,11 @@ template <class T>
struct PtrToArg<T *> { struct PtrToArg<T *> {
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object"); static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
_FORCE_INLINE_ static T *convert(const void *p_ptr) { _FORCE_INLINE_ static T *convert(const void *p_ptr) {
return reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))); return likely(p_ptr) ? reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
} }
typedef Object *EncodeT; typedef Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
*reinterpret_cast<const void **>(p_ptr) = p_var ? p_var->_owner : nullptr; *reinterpret_cast<const void **>(p_ptr) = likely(p_var) ? p_var->_owner : nullptr;
} }
}; };
@ -182,11 +182,11 @@ template <class T>
struct PtrToArg<const T *> { struct PtrToArg<const T *> {
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object"); static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
_FORCE_INLINE_ static const T *convert(const void *p_ptr) { _FORCE_INLINE_ static const T *convert(const void *p_ptr) {
return reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))); return likely(p_ptr) ? reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)))) : nullptr;
} }
typedef const Object *EncodeT; typedef const Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
*reinterpret_cast<const void **>(p_ptr) = p_var ? p_var->_owner : nullptr; *reinterpret_cast<const void **>(p_ptr) = likely(p_var) ? p_var->_owner : nullptr;
} }
}; };

View File

@ -184,6 +184,10 @@ func _ready():
control.queue_free() control.queue_free()
sprite.queue_free() sprite.queue_free()
# Test that passing null for objects works as expected too.
var example_null : Example = null
assert_equal(example.test_object_cast_to_node(example_null), false)
# Test conversions to and from Variant. # Test conversions to and from Variant.
assert_equal(example.test_variant_vector2i_conversion(Vector2i(1, 1)), Vector2i(1, 1)) assert_equal(example.test_variant_vector2i_conversion(Vector2i(1, 1)), Vector2i(1, 1))
assert_equal(example.test_variant_vector2i_conversion(Vector2(1.0, 1.0)), Vector2i(1, 1)) assert_equal(example.test_variant_vector2i_conversion(Vector2(1.0, 1.0)), Vector2i(1, 1))