Don't box params on Native->C# calls with Variant params
Godot uses Variant parameters for calls to script methods. Up until now we were boxing such parameters when marshalling them for invokation, even if they were value types. Now Godot allocates the marshalled parameters on the stack, reducing the GC allocations resulted from boxing.
This commit is contained in:
parent
04bef80b42
commit
a946f84e3d
|
@ -290,7 +290,7 @@ bool GDMonoClass::has_public_parameterless_ctor() {
|
|||
return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC;
|
||||
}
|
||||
|
||||
GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
|
||||
GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, uint16_t p_params_count) {
|
||||
MethodKey key = MethodKey(p_name, p_params_count);
|
||||
|
||||
GDMonoMethod **match = methods.getptr(key);
|
||||
|
@ -330,7 +330,7 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
|
|||
return get_method(p_raw_method, p_name, params_count);
|
||||
}
|
||||
|
||||
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count) {
|
||||
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, uint16_t p_params_count) {
|
||||
ERR_FAIL_NULL_V(p_raw_method, nullptr);
|
||||
|
||||
MethodKey key = MethodKey(p_name, p_params_count);
|
||||
|
|
|
@ -59,13 +59,12 @@ class GDMonoClass {
|
|||
|
||||
MethodKey() {}
|
||||
|
||||
MethodKey(const StringName &p_name, int p_params_count) {
|
||||
name = p_name;
|
||||
params_count = p_params_count;
|
||||
MethodKey(const StringName &p_name, uint16_t p_params_count) :
|
||||
name(p_name), params_count(p_params_count) {
|
||||
}
|
||||
|
||||
StringName name;
|
||||
int params_count;
|
||||
uint16_t params_count = 0;
|
||||
};
|
||||
|
||||
StringName namespace_name;
|
||||
|
@ -139,10 +138,10 @@ public:
|
|||
bool implements_interface(GDMonoClass *p_interface);
|
||||
bool has_public_parameterless_ctor();
|
||||
|
||||
GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
|
||||
GDMonoMethod *get_method(const StringName &p_name, uint16_t p_params_count = 0);
|
||||
GDMonoMethod *get_method(MonoMethod *p_raw_method);
|
||||
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name);
|
||||
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count);
|
||||
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, uint16_t p_params_count);
|
||||
GDMonoMethod *get_method_with_desc(const String &p_description, bool p_include_namespace);
|
||||
|
||||
GDMonoField *get_field(const StringName &p_name);
|
||||
|
|
|
@ -46,29 +46,15 @@ void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) {
|
|||
}
|
||||
|
||||
void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_value) {
|
||||
#define SET_FROM_STRUCT(m_type) \
|
||||
{ \
|
||||
GDMonoMarshal::M_##m_type from = MARSHALLED_OUT(m_type, p_value.operator ::m_type()); \
|
||||
mono_field_set_value(p_object, mono_field, &from); \
|
||||
}
|
||||
|
||||
#define SET_FROM_ARRAY(m_type) \
|
||||
{ \
|
||||
MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator ::m_type()); \
|
||||
mono_field_set_value(p_object, mono_field, managed); \
|
||||
}
|
||||
|
||||
switch (type.type_encoding) {
|
||||
case MONO_TYPE_BOOLEAN: {
|
||||
MonoBoolean val = p_value.operator bool();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_CHAR: {
|
||||
int16_t val = p_value.operator unsigned short();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_I1: {
|
||||
int8_t val = p_value.operator signed char();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
|
@ -85,7 +71,6 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
int64_t val = p_value.operator int64_t();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_U1: {
|
||||
uint8_t val = p_value.operator unsigned char();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
|
@ -102,93 +87,92 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
uint64_t val = p_value.operator uint64_t();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_R4: {
|
||||
float val = p_value.operator float();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_R8: {
|
||||
double val = p_value.operator double();
|
||||
mono_field_set_value(p_object, mono_field, &val);
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_STRING: {
|
||||
if (p_value.get_type() == Variant::NIL) {
|
||||
// Otherwise, Variant -> String would return the string "Null"
|
||||
MonoString *mono_string = nullptr;
|
||||
mono_field_set_value(p_object, mono_field, mono_string);
|
||||
} else {
|
||||
MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
|
||||
mono_field_set_value(p_object, mono_field, mono_string);
|
||||
}
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_VALUETYPE: {
|
||||
GDMonoClass *tclass = type.type_class;
|
||||
|
||||
if (tclass == CACHED_CLASS(Vector2)) {
|
||||
SET_FROM_STRUCT(Vector2);
|
||||
GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_value.operator ::Vector2());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Vector2i)) {
|
||||
SET_FROM_STRUCT(Vector2i);
|
||||
GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_value.operator ::Vector2i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Rect2)) {
|
||||
SET_FROM_STRUCT(Rect2);
|
||||
GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_value.operator ::Rect2());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Rect2i)) {
|
||||
SET_FROM_STRUCT(Rect2i);
|
||||
GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_value.operator ::Rect2i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Transform2D)) {
|
||||
SET_FROM_STRUCT(Transform2D);
|
||||
GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Vector3)) {
|
||||
SET_FROM_STRUCT(Vector3);
|
||||
GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_value.operator ::Vector3());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Vector3i)) {
|
||||
SET_FROM_STRUCT(Vector3i);
|
||||
GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Basis)) {
|
||||
SET_FROM_STRUCT(Basis);
|
||||
GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Quat)) {
|
||||
SET_FROM_STRUCT(Quat);
|
||||
GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Transform)) {
|
||||
SET_FROM_STRUCT(Transform);
|
||||
GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(AABB)) {
|
||||
SET_FROM_STRUCT(AABB);
|
||||
GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Color)) {
|
||||
SET_FROM_STRUCT(Color);
|
||||
GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tclass == CACHED_CLASS(Plane)) {
|
||||
SET_FROM_STRUCT(Plane);
|
||||
GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_value.operator ::Plane());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -267,118 +251,35 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
|
||||
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + tclass->get_name() + "'.");
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_STRING: {
|
||||
if (p_value.get_type() == Variant::NIL) {
|
||||
// Otherwise, Variant -> String would return the string "Null"
|
||||
MonoString *mono_string = nullptr;
|
||||
mono_field_set_value(p_object, mono_field, mono_string);
|
||||
} else {
|
||||
MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
|
||||
mono_field_set_value(p_object, mono_field, mono_string);
|
||||
}
|
||||
} break;
|
||||
case MONO_TYPE_ARRAY:
|
||||
case MONO_TYPE_SZARRAY: {
|
||||
MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type());
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
|
||||
SET_FROM_ARRAY(Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
|
||||
SET_FROM_ARRAY(PackedByteArray);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
|
||||
SET_FROM_ARRAY(PackedInt32Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
|
||||
SET_FROM_ARRAY(PackedInt64Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(float)) {
|
||||
SET_FROM_ARRAY(PackedFloat32Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(double)) {
|
||||
SET_FROM_ARRAY(PackedFloat64Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(String)) {
|
||||
SET_FROM_ARRAY(PackedStringArray);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
|
||||
SET_FROM_ARRAY(PackedVector2Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
|
||||
SET_FROM_ARRAY(PackedVector3Array);
|
||||
break;
|
||||
}
|
||||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
|
||||
SET_FROM_ARRAY(PackedColorArray);
|
||||
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);
|
||||
MonoArray *managed = GDMonoMarshal::variant_to_mono_array(p_value, type.type_class);
|
||||
if (likely(managed != nullptr)) {
|
||||
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;
|
||||
|
||||
case MONO_TYPE_CLASS: {
|
||||
GDMonoClass *type_class = type.type_class;
|
||||
|
||||
// GodotObject
|
||||
if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
|
||||
MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
|
||||
MonoObject *managed = GDMonoMarshal::variant_to_mono_object_of_class(p_value, type.type_class);
|
||||
if (likely(managed != nullptr)) {
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
}
|
||||
} break;
|
||||
case MONO_TYPE_GENERICINST: {
|
||||
MonoObject *managed = GDMonoMarshal::variant_to_mono_object_of_genericinst(p_value, type.type_class);
|
||||
if (likely(managed != nullptr)) {
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CACHED_CLASS(StringName) == type_class) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CACHED_CLASS(NodePath) == type_class) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
if (CACHED_CLASS(RID) == type_class) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// Godot.Collections.Dictionary or IDictionary
|
||||
if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// Godot.Collections.Array or ICollection or IEnumerable
|
||||
if (CACHED_CLASS(Array) == type_class ||
|
||||
type_class == CACHED_CLASS(System_Collections_ICollection) ||
|
||||
type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_OBJECT: {
|
||||
// Variant
|
||||
switch (p_value.get_type()) {
|
||||
|
@ -404,43 +305,56 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
mono_field_set_value(p_object, mono_field, mono_string);
|
||||
} break;
|
||||
case Variant::VECTOR2: {
|
||||
SET_FROM_STRUCT(Vector2);
|
||||
GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_value.operator ::Vector2());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::VECTOR2I: {
|
||||
SET_FROM_STRUCT(Vector2i);
|
||||
GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_value.operator ::Vector2i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::RECT2: {
|
||||
SET_FROM_STRUCT(Rect2);
|
||||
GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_value.operator ::Rect2());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::RECT2I: {
|
||||
SET_FROM_STRUCT(Rect2i);
|
||||
GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_value.operator ::Rect2i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::VECTOR3: {
|
||||
SET_FROM_STRUCT(Vector3);
|
||||
GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_value.operator ::Vector3());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::VECTOR3I: {
|
||||
SET_FROM_STRUCT(Vector3i);
|
||||
GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::TRANSFORM2D: {
|
||||
SET_FROM_STRUCT(Transform2D);
|
||||
GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::PLANE: {
|
||||
SET_FROM_STRUCT(Plane);
|
||||
GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_value.operator ::Plane());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::QUAT: {
|
||||
SET_FROM_STRUCT(Quat);
|
||||
GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_value.operator ::Quat());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::AABB: {
|
||||
SET_FROM_STRUCT(AABB);
|
||||
GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::BASIS: {
|
||||
SET_FROM_STRUCT(Basis);
|
||||
GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::TRANSFORM: {
|
||||
SET_FROM_STRUCT(Transform);
|
||||
GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_value.operator ::Transform());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::COLOR: {
|
||||
SET_FROM_STRUCT(Color);
|
||||
GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color());
|
||||
mono_field_set_value(p_object, mono_field, &from);
|
||||
} break;
|
||||
case Variant::STRING_NAME: {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator StringName());
|
||||
|
@ -475,106 +389,49 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_BYTE_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedByteArray);
|
||||
MonoArray *managed = GDMonoMarshal::PackedByteArray_to_mono_array(p_value.operator ::PackedByteArray());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_INT32_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedInt32Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedInt32Array_to_mono_array(p_value.operator ::PackedInt32Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_INT64_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedInt64Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedInt64Array_to_mono_array(p_value.operator ::PackedInt64Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_FLOAT32_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedFloat32Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedFloat32Array_to_mono_array(p_value.operator ::PackedFloat32Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_FLOAT64_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedFloat64Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedFloat64Array_to_mono_array(p_value.operator ::PackedFloat64Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_STRING_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedStringArray);
|
||||
MonoArray *managed = GDMonoMarshal::PackedStringArray_to_mono_array(p_value.operator ::PackedStringArray());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_VECTOR2_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedVector2Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedVector2Array_to_mono_array(p_value.operator ::PackedVector2Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_VECTOR3_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedVector3Array);
|
||||
MonoArray *managed = GDMonoMarshal::PackedVector3Array_to_mono_array(p_value.operator ::PackedVector3Array());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
case Variant::PACKED_COLOR_ARRAY: {
|
||||
SET_FROM_ARRAY(PackedColorArray);
|
||||
MonoArray *managed = GDMonoMarshal::PackedColorArray_to_mono_array(p_value.operator ::PackedColorArray());
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_GENERICINST: {
|
||||
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
|
||||
|
||||
// Godot.Collections.Dictionary<TKey, TValue>
|
||||
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// Godot.Collections.Array<T>
|
||||
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// System.Collections.Generic.Dictionary<TKey, TValue>
|
||||
if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
|
||||
MonoReflectionType *key_reftype = nullptr;
|
||||
MonoReflectionType *value_reftype = nullptr;
|
||||
GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
|
||||
MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
|
||||
type.type_class, key_reftype, value_reftype);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// System.Collections.Generic.List<T>
|
||||
if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
|
||||
MonoReflectionType *elem_reftype = nullptr;
|
||||
GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
|
||||
MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
|
||||
type.type_class, elem_reftype);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// IDictionary<TKey, TValue>
|
||||
if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
|
||||
MonoReflectionType *key_reftype;
|
||||
MonoReflectionType *value_reftype;
|
||||
GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
|
||||
GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
|
||||
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
// ICollection<T> or IEnumerable<T>
|
||||
if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
|
||||
MonoReflectionType *elem_reftype;
|
||||
GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
|
||||
GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
|
||||
|
||||
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
ERR_PRINT("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + ".");
|
||||
} break;
|
||||
}
|
||||
|
||||
#undef SET_FROM_ARRAY_AND_BREAK
|
||||
#undef SET_FROM_STRUCT_AND_BREAK
|
||||
}
|
||||
|
||||
MonoObject *GDMonoField::get_value(MonoObject *p_object) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -90,15 +90,40 @@ _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
|
|||
|
||||
// Variant
|
||||
|
||||
MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type);
|
||||
MonoObject *variant_to_mono_object(const Variant *p_var);
|
||||
size_t variant_get_managed_unboxed_size(const ManagedType &p_type);
|
||||
void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type, void *r_buffer, unsigned int &r_offset);
|
||||
MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type);
|
||||
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var) {
|
||||
return variant_to_mono_object(&p_var);
|
||||
MonoObject *variant_to_mono_object(const Variant &p_var);
|
||||
MonoArray *variant_to_mono_array(const Variant &p_var, GDMonoClass *p_type_class);
|
||||
MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p_type_class);
|
||||
MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoClass *p_type_class);
|
||||
MonoString *variant_to_mono_string(const Variant &p_var);
|
||||
|
||||
// These overloads were added to avoid passing a `const Variant *` to the `const Variant &`
|
||||
// parameter. That would result in the `Variant(bool)` copy constructor being called as
|
||||
// pointers are implicitly converted to bool. Implicit conversions are f-ing evil.
|
||||
|
||||
_FORCE_INLINE_ void *variant_to_managed_unboxed(const Variant *p_var, const ManagedType &p_type, void *r_buffer, unsigned int &r_offset) {
|
||||
return variant_to_managed_unboxed(*p_var, p_type, r_buffer, r_offset);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) {
|
||||
return variant_to_mono_object(&p_var, p_type);
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) {
|
||||
return variant_to_mono_object(*p_var, p_type);
|
||||
}
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var) {
|
||||
return variant_to_mono_object(*p_var);
|
||||
}
|
||||
_FORCE_INLINE_ MonoArray *variant_to_mono_array(const Variant *p_var, GDMonoClass *p_type_class) {
|
||||
return variant_to_mono_array(*p_var, p_type_class);
|
||||
}
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object_of_class(const Variant *p_var, GDMonoClass *p_type_class) {
|
||||
return variant_to_mono_object_of_class(*p_var, p_type_class);
|
||||
}
|
||||
_FORCE_INLINE_ MonoObject *variant_to_mono_object_of_genericinst(const Variant *p_var, GDMonoClass *p_type_class) {
|
||||
return variant_to_mono_object_of_genericinst(*p_var, p_type_class);
|
||||
}
|
||||
_FORCE_INLINE_ MonoString *variant_to_mono_string(const Variant *p_var) {
|
||||
return variant_to_mono_string(*p_var);
|
||||
}
|
||||
|
||||
Variant mono_object_to_variant(MonoObject *p_obj);
|
||||
|
@ -120,7 +145,7 @@ Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, Mono
|
|||
// Array
|
||||
|
||||
MonoArray *Array_to_mono_array(const Array &p_array);
|
||||
MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
|
||||
MonoArray *Array_to_mono_array(const Array &p_array, MonoClass *p_array_type_class);
|
||||
Array mono_array_to_Array(MonoArray *p_array);
|
||||
|
||||
// PackedInt32Array
|
||||
|
|
|
@ -75,6 +75,10 @@ void GDMonoMethod::_update_signature(MonoMethodSignature *p_method_sig) {
|
|||
// clear the cache
|
||||
method_info_fetched = false;
|
||||
method_info = MethodInfo();
|
||||
|
||||
for (int i = 0; i < params_count; i++) {
|
||||
params_buffer_size += GDMonoMarshal::variant_get_managed_unboxed_size(param_types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GDMonoClass *GDMonoMethod::get_enclosing_class() const {
|
||||
|
@ -107,14 +111,15 @@ MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params,
|
|||
MonoObject *ret;
|
||||
|
||||
if (params_count > 0) {
|
||||
MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), params_count);
|
||||
void **params = (void **)alloca(params_count * sizeof(void *));
|
||||
uint8_t *buffer = (uint8_t *)alloca(params_buffer_size);
|
||||
unsigned int offset = 0;
|
||||
|
||||
for (int i = 0; i < params_count; i++) {
|
||||
MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]);
|
||||
mono_array_setref(params, i, boxed_param);
|
||||
params[i] = GDMonoMarshal::variant_to_managed_unboxed(p_params[i], param_types[i], buffer + offset, offset);
|
||||
}
|
||||
|
||||
ret = GDMonoUtils::runtime_invoke_array(mono_method, p_object, params, &exc);
|
||||
ret = GDMonoUtils::runtime_invoke(mono_method, p_object, params, &exc);
|
||||
} else {
|
||||
ret = GDMonoUtils::runtime_invoke(mono_method, p_object, nullptr, &exc);
|
||||
}
|
||||
|
@ -279,16 +284,8 @@ const MethodInfo &GDMonoMethod::get_method_info() {
|
|||
return method_info;
|
||||
}
|
||||
|
||||
GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) {
|
||||
name = p_name;
|
||||
|
||||
mono_method = p_method;
|
||||
|
||||
method_info_fetched = false;
|
||||
|
||||
attrs_fetched = false;
|
||||
attributes = nullptr;
|
||||
|
||||
GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) :
|
||||
name(p_name), mono_method(p_method) {
|
||||
_update_signature();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,15 +38,16 @@
|
|||
class GDMonoMethod : public IMonoClassMember {
|
||||
StringName name;
|
||||
|
||||
int params_count;
|
||||
uint16_t params_count;
|
||||
unsigned int params_buffer_size = 0;
|
||||
ManagedType return_type;
|
||||
Vector<ManagedType> param_types;
|
||||
|
||||
bool method_info_fetched;
|
||||
bool method_info_fetched = false;
|
||||
MethodInfo method_info;
|
||||
|
||||
bool attrs_fetched;
|
||||
MonoCustomAttrInfo *attributes;
|
||||
bool attrs_fetched = false;
|
||||
MonoCustomAttrInfo *attributes = nullptr;
|
||||
|
||||
void _update_signature();
|
||||
void _update_signature(MonoMethodSignature *p_method_sig);
|
||||
|
@ -72,7 +73,7 @@ public:
|
|||
|
||||
_FORCE_INLINE_ MonoMethod *get_mono_ptr() const { return mono_method; }
|
||||
|
||||
_FORCE_INLINE_ int get_parameters_count() const { return params_count; }
|
||||
_FORCE_INLINE_ uint16_t get_parameters_count() const { return params_count; }
|
||||
_FORCE_INLINE_ ManagedType get_return_type() const { return return_type; }
|
||||
|
||||
MonoObject *invoke(MonoObject *p_object, const Variant **p_params, MonoException **r_exc = nullptr) const;
|
||||
|
|
|
@ -149,10 +149,9 @@ bool GDMonoProperty::has_setter() {
|
|||
|
||||
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) {
|
||||
MonoMethod *prop_method = mono_property_get_set_method(mono_property);
|
||||
MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 1);
|
||||
mono_array_setref(params, 0, p_value);
|
||||
void *params[1] = { p_value };
|
||||
MonoException *exc = nullptr;
|
||||
GDMonoUtils::runtime_invoke_array(prop_method, p_object, params, &exc);
|
||||
GDMonoUtils::runtime_invoke(prop_method, p_object, params, &exc);
|
||||
if (exc) {
|
||||
if (r_exc) {
|
||||
*r_exc = exc;
|
||||
|
|
|
@ -498,13 +498,6 @@ MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, M
|
|||
return ret;
|
||||
}
|
||||
|
||||
MonoObject *runtime_invoke_array(MonoMethod *p_method, void *p_obj, MonoArray *p_params, MonoException **r_exc) {
|
||||
GD_MONO_BEGIN_RUNTIME_INVOKE;
|
||||
MonoObject *ret = mono_runtime_invoke_array(p_method, p_obj, p_params, (MonoObject **)r_exc);
|
||||
GD_MONO_END_RUNTIME_INVOKE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MonoString *object_to_string(MonoObject *p_obj, MonoException **r_exc) {
|
||||
GD_MONO_BEGIN_RUNTIME_INVOKE;
|
||||
MonoString *ret = mono_object_to_string(p_obj, (MonoObject **)r_exc);
|
||||
|
|
|
@ -135,7 +135,6 @@ _FORCE_INLINE_ int &get_runtime_invoke_count_ref() {
|
|||
}
|
||||
|
||||
MonoObject *runtime_invoke(MonoMethod *p_method, void *p_obj, void **p_params, MonoException **r_exc);
|
||||
MonoObject *runtime_invoke_array(MonoMethod *p_method, void *p_obj, MonoArray *p_params, MonoException **r_exc);
|
||||
|
||||
MonoString *object_to_string(MonoObject *p_obj, MonoException **r_exc);
|
||||
|
||||
|
|
|
@ -109,11 +109,15 @@ void SignalAwaiterCallable::call(const Variant **p_arguments, int p_argcount, Va
|
|||
"Resumed after await, but class instance is gone.");
|
||||
#endif
|
||||
|
||||
MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount);
|
||||
MonoArray *signal_args = nullptr;
|
||||
|
||||
for (int i = 0; i < p_argcount; i++) {
|
||||
MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]);
|
||||
mono_array_setref(signal_args, i, boxed);
|
||||
if (p_argcount > 0) {
|
||||
signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_argcount);
|
||||
|
||||
for (int i = 0; i < p_argcount; i++) {
|
||||
MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_arguments[i]);
|
||||
mono_array_setref(signal_args, i, boxed);
|
||||
}
|
||||
}
|
||||
|
||||
MonoObject *awaiter = awaiter_handle.get_target();
|
||||
|
|
Loading…
Reference in New Issue