From 059750cd0d52036158a0c0c747c7959136403898 Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Fri, 8 Oct 2021 20:00:50 +0200 Subject: [PATCH] Support marshaling generic Godot.Object Allows using generic C# types in signals as long as they inherit from `Godot.Object`. --- modules/mono/mono_gd/gd_mono_field.cpp | 7 +++++++ modules/mono/mono_gd/gd_mono_marshal.cpp | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index f19cc88f3f9..0f6a798a03b 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -493,6 +493,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ mono_field_set_value(p_object, mono_field, managed); break; } + + // GodotObject + GDMonoClass *type_class = type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *()); + mono_field_set_value(p_object, mono_field, managed); + } } break; default: { diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 40c6b4ed656..948c96d498b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -206,6 +206,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { return Variant::ARRAY; } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + return Variant::OBJECT; + } } break; default: { @@ -682,6 +688,12 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class); } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); + } } break; } break; } @@ -878,6 +890,17 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype); } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + Object *ptr = unbox(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); + if (ptr != NULL) { + Reference *ref = Object::cast_to(ptr); + return ref ? Variant(Ref(ref)) : Variant(ptr); + } + return Variant(); + } } break; }