|
@@ -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) {
|