diff options
author | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2020-01-02 13:54:16 +0100 |
---|---|---|
committer | Ignacio Etcheverry <ignalfonsore@gmail.com> | 2020-01-02 13:54:20 +0100 |
commit | 844a8d215b1fa768440d5233c532f6e71c54fc14 (patch) | |
tree | eae988c1ae1d36466f5ceca09e0eee57e62bb8d8 /modules/mono/mono_gd/gd_mono_marshal.cpp | |
parent | ea75ea50d2b0f76c44e02e6fd8a558788cc375f6 (diff) |
Mono/C#: Make 'GD.Print' and its variants fallback to 'ToString()'
Up until now, 'GD.Print' would convert parameters first to
Variant and only then to String. This meant parameters that cannot be
converted to Variant would be printed as "Null".
This commit makes 'GD.Print' fallback to 'System.Object.ToString()'
if the parameter could not be converted to Variant.
The same applies to all 'GD.Print' variants:
'GD.PrintS', 'GD.PrintT', 'GD.PrintErr' and 'GD.PrintRaw'.
Diffstat (limited to 'modules/mono/mono_gd/gd_mono_marshal.cpp')
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 24fcd27bbb..b81c20348d 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -700,15 +700,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); } -Variant mono_object_to_variant(MonoObject *p_obj) { - if (!p_obj) - return Variant(); +Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) { - ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); - - ERR_FAIL_COND_V(!type.type_class, Variant()); + ERR_FAIL_COND_V(!p_type.type_class, Variant()); - switch (type.type_encoding) { + switch (p_type.type_encoding) { case MONO_TYPE_BOOLEAN: return (bool)unbox<MonoBoolean>(p_obj); @@ -745,7 +741,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) { } break; case MONO_TYPE_VALUETYPE: { - GDMonoClass *vtclass = type.type_class; + GDMonoClass *vtclass = p_type.type_class; if (vtclass == CACHED_CLASS(Vector2)) return MARSHALLED_IN(Vector2, (GDMonoMarshal::M_Vector2 *)mono_object_unbox(p_obj)); @@ -783,7 +779,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) { case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { - MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type()); + MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) return mono_array_to_Array((MonoArray *)p_obj); @@ -809,11 +805,15 @@ Variant mono_object_to_variant(MonoObject *p_obj) { if (array_type->eklass == CACHED_CLASS_RAW(Color)) return mono_array_to_PoolColorArray((MonoArray *)p_obj); - ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); + if (p_fail_with_err) { + ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); + } else { + return Variant(); + } } break; case MONO_TYPE_CLASS: { - GDMonoClass *type_class = type.type_class; + GDMonoClass *type_class = p_type.type_class; // GodotObject if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { @@ -871,18 +871,18 @@ Variant mono_object_to_variant(MonoObject *p_obj) { } break; case MONO_TYPE_GENERICINST: { - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoException *exc = NULL; - MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); + MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return *unbox<Dictionary *>(ret); } if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoException *exc = NULL; - MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); + MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return *unbox<Array *>(ret); } @@ -893,7 +893,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) { return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { + if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj); } @@ -901,14 +901,62 @@ Variant mono_object_to_variant(MonoObject *p_obj) { return GDMonoUtils::Marshal::enumerable_to_array(p_obj); } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { + if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { return GDMonoUtils::Marshal::enumerable_to_array(p_obj); } } break; } - ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + - type.type_class->get_name() + "' Encoding: " + itos(type.type_encoding) + "."); + if (p_fail_with_err) { + ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + + p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); + } else { + return Variant(); + } +} + +Variant mono_object_to_variant(MonoObject *p_obj) { + if (!p_obj) + return Variant(); + + ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); + + return mono_object_to_variant_impl(p_obj, type); +} + +Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { + if (!p_obj) + return Variant(); + + return mono_object_to_variant_impl(p_obj, p_type); +} + +Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) { + if (!p_obj) + return Variant(); + + return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false); +} + +String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { + ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); + Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj, type); + + if (var.get_type() == Variant::NIL && p_obj != NULL) { + // Cannot convert MonoObject* to Variant; fallback to 'ToString()'. + MonoException *exc = NULL; + MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc); + + if (exc) { + if (r_exc) + *r_exc = exc; + return String(); + } + + return GDMonoMarshal::mono_string_to_godot(mono_str); + } else { + return var.operator String(); + } } MonoArray *Array_to_mono_array(const Array &p_array) { |