Fix Variant Ref<> assignment.

-Creating from object pointer via funcptr API was missing reference initialization.
-Supersedes https://github.com/godotengine/godot-cpp/pull/662
-Fixes several crashes in GDExtension
This commit is contained in:
reduz 2022-02-11 12:30:49 +01:00
parent 3aa7b7eaf2
commit 3ad3a43063
3 changed files with 21 additions and 4 deletions

View File

@ -1023,6 +1023,13 @@ bool Variant::is_null() const {
}
}
bool Variant::initialize_ref(Object *p_object) {
RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object));
if (!ref_counted->init_ref()) {
return false;
}
return true;
}
void Variant::reference(const Variant &p_variant) {
switch (type) {
case NIL:

View File

@ -216,6 +216,7 @@ private:
} _data alignas(8);
void reference(const Variant &p_variant);
static bool initialize_ref(Object *p_object);
void _clear_internal();

View File

@ -111,6 +111,10 @@ public:
}
}
_FORCE_INLINE_ static bool initialize_ref(Object *object) {
return Variant::initialize_ref(object);
}
// Atomic types.
_FORCE_INLINE_ static bool *get_bool(Variant *v) { return &v->_data._bool; }
_FORCE_INLINE_ static const bool *get_bool(const Variant *v) { return &v->_data._bool; }
@ -1430,10 +1434,15 @@ struct VariantTypeConstructor<Object *> {
_FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) {
Variant *variant = reinterpret_cast<Variant *>(p_variant);
VariantInitializer<Object *>::init(variant);
Object *value = *(reinterpret_cast<Object **>(p_value));
if (value) {
VariantInternalAccessor<Object *>::set(variant, value);
VariantInternalAccessor<ObjectID>::set(variant, value->get_instance_id());
Object *object = *(reinterpret_cast<Object **>(p_value));
if (object) {
if (object->is_ref_counted()) {
if (!VariantInternal::initialize_ref(object)) {
return;
}
}
VariantInternalAccessor<Object *>::set(variant, object);
VariantInternalAccessor<ObjectID>::set(variant, object->get_instance_id());
}
}