Skip to content

Commit

Permalink
Merge pull request #38117 from neikeq/export-mono-array-godot-object
Browse files Browse the repository at this point in the history
Mono/C#: Allow exporting System.Array of type Godot.Object
  • Loading branch information
neikeq authored Apr 22, 2020
2 parents 5d29f42 + 0fec3cb commit 28f0b15
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
7 changes: 7 additions & 0 deletions modules/mono/mono_gd/gd_mono_field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}

GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}

ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;

Expand Down
31 changes: 31 additions & 0 deletions modules/mono/mono_gd/gd_mono_marshal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_

if (array_type->eklass == CACHED_CLASS_RAW(Color))
return Variant::PACKED_COLOR_ARRAY;

GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
return Variant::ARRAY;
} break;

case MONO_TYPE_CLASS: {
Expand Down Expand Up @@ -252,6 +256,13 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_

bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) {
switch (p_array_type.type_encoding) {
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type());
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
r_elem_type = ManagedType::from_class(array_type_class);
return true;
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type());

Expand Down Expand Up @@ -577,6 +588,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());

GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);

ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;

Expand Down Expand Up @@ -922,6 +937,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return mono_array_to_PackedColorArray((MonoArray *)p_obj);

GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
return mono_array_to_Array((MonoArray *)p_obj);

if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
} else {
Expand Down Expand Up @@ -1093,6 +1112,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
return ret;
}

MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
int length = p_array.size();
MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);

for (int i = 0; i < length; i++) {
MonoObject *boxed = variant_to_mono_object(p_array[i]);
mono_array_setref(ret, i, boxed);
}

return ret;
}

Array mono_array_to_Array(MonoArray *p_array) {
Array ret;
if (!p_array)
Expand Down
1 change: 1 addition & 0 deletions modules/mono/mono_gd/gd_mono_marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
// Array

MonoArray *Array_to_mono_array(const Array &p_array);
MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
Array mono_array_to_Array(MonoArray *p_array);

// PackedInt32Array
Expand Down

0 comments on commit 28f0b15

Please sign in to comment.