Exemplo n.º 1
0
GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) {

	GDMonoClass *match = NULL;

	if (gdobject_class_cache_updated) {
		Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);

		if (result)
			match = result->get();
	} else {
		List<GDMonoClass *> nested_classes;

		int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF);

		for (int i = 1; i < rows; i++) {
			MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);

			if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class))
				continue;

			GDMonoClass *current = get_class(mono_class);

			if (!current)
				continue;

			nested_classes.push_back(current);

			if (!match && current->get_name() == p_class)
				match = current;

			while (!nested_classes.empty()) {
				GDMonoClass *current_nested = nested_classes.front()->get();
				nested_classes.pop_back();

				void *iter = NULL;

				while (true) {
					MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_raw(), &iter);

					if (!raw_nested)
						break;

					GDMonoClass *nested_class = get_class(raw_nested);

					if (nested_class) {
						gdobject_class_cache.insert(nested_class->get_name(), nested_class);
						nested_classes.push_back(nested_class);
					}
				}
			}

			gdobject_class_cache.insert(current->get_name(), current);
		}

		gdobject_class_cache_updated = true;
	}

	return match;
}
Exemplo n.º 2
0
MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array) {
	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), p_array.size());

	for (int i = 0; i < p_array.size(); i++) {
		mono_array_set(ret, uint8_t, i, p_array[i]);
	}

	return ret;
}
Exemplo n.º 3
0
MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) {
	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_array.size());

	for (int i = 0; i < p_array.size(); i++) {
		MonoString *boxed = mono_string_from_godot(p_array[i]);
		mono_array_set(ret, MonoString *, i, boxed);
	}

	return ret;
}
Exemplo n.º 4
0
MonoArray *Array_to_mono_array(const Array &p_array) {
	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_array.size());

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

	return ret;
}
Exemplo n.º 5
0
MonoObject *create_managed_from(const NodePath &p_from) {
	MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(NodePath));
	ERR_FAIL_NULL_V(mono_object, NULL);

	// Construct
	mono_runtime_object_init(mono_object);

	CACHED_FIELD(NodePath, ptr)->set_value_raw(mono_object, memnew(NodePath(p_from)));

	return mono_object;
}
Exemplo n.º 6
0
MonoObject *create_managed_from(const RID &p_from) {
	MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(RID));
	ERR_FAIL_NULL_V(mono_object, NULL);

	// Construct
	GDMonoUtils::runtime_object_init(mono_object);

	CACHED_FIELD(RID, ptr)->set_value_raw(mono_object, memnew(RID(p_from)));

	return mono_object;
}
Exemplo n.º 7
0
MonoObject *Dictionary_to_mono_object(const Dictionary &p_dict) {
	MonoArray *keys = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_dict.size());
	MonoArray *values = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_dict.size());

	int i = 0;
	const Variant *dkey = NULL;
	while ((dkey = p_dict.next(dkey))) {
		mono_array_set(keys, MonoObject *, i, variant_to_mono_object(dkey));
		mono_array_set(values, MonoObject *, i, variant_to_mono_object(p_dict[*dkey]));
		i++;
	}

	GDMonoUtils::MarshalUtils_ArraysToDict arrays_to_dict = CACHED_METHOD_THUNK(MarshalUtils, ArraysToDictionary);

	MonoObject *ex = NULL;
	MonoObject *ret = arrays_to_dict(keys, values, &ex);

	if (ex) {
		mono_print_unhandled_exception(ex);
		ERR_FAIL_V(NULL);
	}

	return ret;
}
Exemplo n.º 8
0
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
	List<PropertyInfo> property_list;
	p_ptr->get_property_list(&property_list);

	MonoArray *result = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), property_list.size());

	int i = 0;
	for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
		MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get().name);
		mono_array_set(result, MonoString *, i, boxed);
		i++;
	}

	return result;
}
Exemplo n.º 9
0
Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {

#ifdef DEBUG_ENABLED
	if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) {
		ERR_EXPLAIN("Resumed after await, but class instance is gone");
		ERR_FAIL_V(Variant());
	}
#endif

	if (p_argcount < 1) {
		r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
		r_error.argument = 1;
		return Variant();
	}

	Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1];

	if (self.is_null()) {
		r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
		r_error.argument = p_argcount - 1;
		r_error.expected = Variant::OBJECT;
		return Variant();
	}

	set_completed(true);

	int signal_argc = p_argcount - 1;
	MonoArray *signal_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), signal_argc);

	for (int i = 0; i < signal_argc; i++) {
		MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
		mono_array_set(signal_args, MonoObject *, i, boxed);
	}

	GDMonoUtils::SignalAwaiter_SignalCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback);

	MonoException *exc = NULL;
	GD_MONO_BEGIN_RUNTIME_INVOKE;
	thunk(get_target(), signal_args, (MonoObject **)&exc);
	GD_MONO_END_RUNTIME_INVOKE;

	if (exc) {
		GDMonoUtils::set_pending_exception(exc);
		ERR_FAIL_V(Variant());
	}

	return Variant();
}
Exemplo n.º 10
0
MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array) {
	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), p_array.size());

	for (int i = 0; i < p_array.size(); i++) {
#ifdef YOLOCOPY
		mono_array_set(ret, Vector2, i, p_array[i]);
#else
		real_t *raw = (real_t *)mono_array_addr_with_size(ret, sizeof(real_t) * 2, i);
		const Vector2 &elem = p_array[i];
		raw[0] = elem.x;
		raw[1] = elem.y;
#endif
	}

	return ret;
}
Exemplo n.º 11
0
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoObject **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_set(params, MonoObject *, 0, p_value);

	MonoObject *exc = NULL;
	mono_runtime_invoke_array(prop_method, p_object, params, &exc);

	if (exc) {
		if (r_exc) {
			*r_exc = exc;
		} else {
			GDMonoUtils::print_unhandled_exception(exc);
		}
	}
}
Exemplo n.º 12
0
MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array) {
	MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), p_array.size());

	for (int i = 0; i < p_array.size(); i++) {
#ifdef YOLOCOPY
		mono_array_set(ret, Color, i, p_array[i]);
#else
		real_t *raw = (real_t *)mono_array_addr_with_size(ret, sizeof(real_t) * 4, i);
		const Color &elem = p_array[i];
		raw[0] = elem.r;
		raw[1] = elem.g;
		raw[2] = elem.b;
		raw[3] = elem.a;
#endif
	}

	return ret;
}
Exemplo n.º 13
0
MonoObject *GDMonoMethod::invoke(MonoObject *p_object, const Variant **p_params, MonoObject **r_exc) {
	if (get_return_type().type_encoding != MONO_TYPE_VOID || get_parameters_count() > 0) {
		MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), get_parameters_count());

		for (int i = 0; i < params_count; i++) {
			MonoObject *boxed_param = GDMonoMarshal::variant_to_mono_object(p_params[i], param_types[i]);
			mono_array_set(params, MonoObject *, i, boxed_param);
		}

		MonoObject *exc = NULL;
		MonoObject *ret = mono_runtime_invoke_array(mono_method, p_object, params, &exc);

		if (exc) {
			ret = NULL;
			if (r_exc) {
				*r_exc = exc;
			} else {
				GDMonoUtils::print_unhandled_exception(exc);
			}
		}

		return ret;
	} else {
		MonoObject *exc = NULL;
		mono_runtime_invoke(mono_method, p_object, NULL, &exc);

		if (exc) {
			if (r_exc) {
				*r_exc = exc;
			} else {
				GDMonoUtils::print_unhandled_exception(exc);
			}
		}

		return NULL;
	}
}
Exemplo n.º 14
0
void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
#define SET_FROM_STRUCT_AND_BREAK(m_type)                \
	{                                                    \
		const m_type &val = p_value.operator m_type();   \
		MARSHALLED_OUT(m_type, val, raw);                \
		mono_field_set_value(p_object, mono_field, raw); \
		break;                                           \
	}

#define SET_FROM_PRIMITIVE(m_type)                        \
	{                                                     \
		m_type val = p_value.operator m_type();           \
		mono_field_set_value(p_object, mono_field, &val); \
		break;                                            \
	}

#define SET_FROM_ARRAY_AND_BREAK(m_type)                                                       \
	{                                                                                          \
		MonoArray *managed = GDMonoMarshal::m_type##_to_mono_array(p_value.operator m_type()); \
		mono_field_set_value(p_object, mono_field, &managed);                                  \
		break;                                                                                 \
	}

	switch (type.type_encoding) {
		case MONO_TYPE_BOOLEAN: {
			SET_FROM_PRIMITIVE(bool);
		} break;

		case MONO_TYPE_I1: {
			SET_FROM_PRIMITIVE(signed char);
		} break;
		case MONO_TYPE_I2: {
			SET_FROM_PRIMITIVE(signed short);
		} break;
		case MONO_TYPE_I4: {
			SET_FROM_PRIMITIVE(signed int);
		} break;
		case MONO_TYPE_I8: {
			SET_FROM_PRIMITIVE(int64_t);
		} break;

		case MONO_TYPE_U1: {
			SET_FROM_PRIMITIVE(unsigned char);
		} break;
		case MONO_TYPE_U2: {
			SET_FROM_PRIMITIVE(unsigned short);
		} break;
		case MONO_TYPE_U4: {
			SET_FROM_PRIMITIVE(unsigned int);
		} break;
		case MONO_TYPE_U8: {
			SET_FROM_PRIMITIVE(uint64_t);
		} break;

		case MONO_TYPE_R4: {
			SET_FROM_PRIMITIVE(float);
		} break;

		case MONO_TYPE_R8: {
			SET_FROM_PRIMITIVE(double);
		} break;

		case MONO_TYPE_STRING: {
			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_AND_BREAK(Vector2);

			if (tclass == CACHED_CLASS(Rect2))
				SET_FROM_STRUCT_AND_BREAK(Rect2);

			if (tclass == CACHED_CLASS(Transform2D))
				SET_FROM_STRUCT_AND_BREAK(Transform2D);

			if (tclass == CACHED_CLASS(Vector3))
				SET_FROM_STRUCT_AND_BREAK(Vector3);

			if (tclass == CACHED_CLASS(Basis))
				SET_FROM_STRUCT_AND_BREAK(Basis);

			if (tclass == CACHED_CLASS(Quat))
				SET_FROM_STRUCT_AND_BREAK(Quat);

			if (tclass == CACHED_CLASS(Transform))
				SET_FROM_STRUCT_AND_BREAK(Transform);

			if (tclass == CACHED_CLASS(AABB))
				SET_FROM_STRUCT_AND_BREAK(AABB);

			if (tclass == CACHED_CLASS(Color))
				SET_FROM_STRUCT_AND_BREAK(Color);

			if (tclass == CACHED_CLASS(Plane))
				SET_FROM_STRUCT_AND_BREAK(Plane);

			if (mono_class_is_enum(tclass->get_raw()))
				SET_FROM_PRIMITIVE(signed int);

			ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());
			ERR_FAIL();
		} break;

		case MONO_TYPE_ARRAY:
		case MONO_TYPE_SZARRAY: {
			MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(type.type_class));

			if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
				SET_FROM_ARRAY_AND_BREAK(Array);

			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
				SET_FROM_ARRAY_AND_BREAK(PoolByteArray);

			if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
				SET_FROM_ARRAY_AND_BREAK(PoolIntArray);

			if (array_type->eklass == REAL_T_MONOCLASS)
				SET_FROM_ARRAY_AND_BREAK(PoolRealArray);

			if (array_type->eklass == CACHED_CLASS_RAW(String))
				SET_FROM_ARRAY_AND_BREAK(PoolStringArray);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
				SET_FROM_ARRAY_AND_BREAK(PoolVector2Array);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
				SET_FROM_ARRAY_AND_BREAK(PoolVector3Array);

			if (array_type->eklass == CACHED_CLASS_RAW(Color))
				SET_FROM_ARRAY_AND_BREAK(PoolColorArray);

			ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
			ERR_FAIL();
		} 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 *());
				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;
			}

			ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name());
			ERR_FAIL();
		} break;

		case MONO_TYPE_OBJECT: {
			// Variant
			switch (p_value.get_type()) {
				case Variant::BOOL: {
					SET_FROM_PRIMITIVE(bool);
				} break;
				case Variant::INT: {
					SET_FROM_PRIMITIVE(int);
				} break;
				case Variant::REAL: {
#ifdef REAL_T_IS_DOUBLE
					SET_FROM_PRIMITIVE(double);
#else
					SET_FROM_PRIMITIVE(float);
#endif
				} break;
				case Variant::STRING: {
					MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
					mono_field_set_value(p_object, mono_field, mono_string);
				} break;
				case Variant::VECTOR2: SET_FROM_STRUCT_AND_BREAK(Vector2);
				case Variant::RECT2: SET_FROM_STRUCT_AND_BREAK(Rect2);
				case Variant::VECTOR3: SET_FROM_STRUCT_AND_BREAK(Vector3);
				case Variant::TRANSFORM2D: SET_FROM_STRUCT_AND_BREAK(Transform2D);
				case Variant::PLANE: SET_FROM_STRUCT_AND_BREAK(Plane);
				case Variant::QUAT: SET_FROM_STRUCT_AND_BREAK(Quat);
				case Variant::AABB: SET_FROM_STRUCT_AND_BREAK(AABB);
				case Variant::BASIS: SET_FROM_STRUCT_AND_BREAK(Basis);
				case Variant::TRANSFORM: SET_FROM_STRUCT_AND_BREAK(Transform);
				case Variant::COLOR: SET_FROM_STRUCT_AND_BREAK(Color);
				case Variant::NODE_PATH: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::_RID: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::OBJECT: {
					MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
					mono_field_set_value(p_object, mono_field, managed);
					break;
				}
				case Variant::DICTIONARY: {
					MonoObject *managed = GDMonoMarshal::Dictionary_to_mono_object(p_value.operator Dictionary());
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::ARRAY: SET_FROM_ARRAY_AND_BREAK(Array);
				case Variant::POOL_BYTE_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolByteArray);
				case Variant::POOL_INT_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolIntArray);
				case Variant::POOL_REAL_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolRealArray);
				case Variant::POOL_STRING_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolStringArray);
				case Variant::POOL_VECTOR2_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolVector2Array);
				case Variant::POOL_VECTOR3_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolVector3Array);
				case Variant::POOL_COLOR_ARRAY: SET_FROM_ARRAY_AND_BREAK(PoolColorArray);
#undef SET_FROM_ARRAY_AND_BREAK
				default: break;
			}
		} break;

		case MONO_TYPE_GENERICINST: {
			if (CACHED_RAW_MONO_CLASS(Dictionary) == type.type_class->get_raw()) {
				MonoObject *managed = GDMonoMarshal::Dictionary_to_mono_object(p_value.operator Dictionary());
				mono_field_set_value(p_object, mono_field, managed);
				break;
			}
		} break;

		default: {
			ERR_PRINTS(String() + "Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding));
		} break;
	}

#undef SET_FROM_STRUCT_AND_BREAK
#undef SET_FROM_PRIMITIVE
}
Exemplo n.º 15
0
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);
		} break;
		case MONO_TYPE_I2: {
			int16_t val = p_value.operator signed short();
			mono_field_set_value(p_object, mono_field, &val);
		} break;
		case MONO_TYPE_I4: {
			int32_t val = p_value.operator signed int();
			mono_field_set_value(p_object, mono_field, &val);
		} break;
		case MONO_TYPE_I8: {
			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);
		} break;
		case MONO_TYPE_U2: {
			uint16_t val = p_value.operator unsigned short();
			mono_field_set_value(p_object, mono_field, &val);
		} break;
		case MONO_TYPE_U4: {
			uint32_t val = p_value.operator unsigned int();
			mono_field_set_value(p_object, mono_field, &val);
		} break;
		case MONO_TYPE_U8: {
			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: {
			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);
				break;
			}

			if (tclass == CACHED_CLASS(Rect2)) {
				SET_FROM_STRUCT(Rect2);
				break;
			}

			if (tclass == CACHED_CLASS(Transform2D)) {
				SET_FROM_STRUCT(Transform2D);
				break;
			}

			if (tclass == CACHED_CLASS(Vector3)) {
				SET_FROM_STRUCT(Vector3);
				break;
			}

			if (tclass == CACHED_CLASS(Basis)) {
				SET_FROM_STRUCT(Basis);
				break;
			}

			if (tclass == CACHED_CLASS(Quat)) {
				SET_FROM_STRUCT(Quat);
				break;
			}

			if (tclass == CACHED_CLASS(Transform)) {
				SET_FROM_STRUCT(Transform);
				break;
			}

			if (tclass == CACHED_CLASS(AABB)) {
				SET_FROM_STRUCT(AABB);
				break;
			}

			if (tclass == CACHED_CLASS(Color)) {
				SET_FROM_STRUCT(Color);
				break;
			}

			if (tclass == CACHED_CLASS(Plane)) {
				SET_FROM_STRUCT(Plane);
				break;
			}

			if (mono_class_is_enum(tclass->get_mono_ptr())) {
				MonoType *enum_basetype = mono_class_enum_basetype(tclass->get_mono_ptr());
				switch (mono_type_get_type(enum_basetype)) {
					case MONO_TYPE_BOOLEAN: {
						MonoBoolean val = p_value.operator bool();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					case MONO_TYPE_CHAR: {
						uint16_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);
						break;
					}
					case MONO_TYPE_I2: {
						int16_t val = p_value.operator signed short();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					case MONO_TYPE_I4: {
						int32_t val = p_value.operator signed int();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					case MONO_TYPE_I8: {
						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);
						break;
					}
					case MONO_TYPE_U2: {
						uint16_t val = p_value.operator unsigned short();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					case MONO_TYPE_U4: {
						uint32_t val = p_value.operator unsigned int();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					case MONO_TYPE_U8: {
						uint64_t val = p_value.operator uint64_t();
						mono_field_set_value(p_object, mono_field, &val);
						break;
					}
					default: {
						ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
						ERR_FAIL();
					}
				}

				break;
			}

			ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());
			ERR_FAIL();
		} 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(PoolByteArray);
				break;
			}

			if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
				SET_FROM_ARRAY(PoolIntArray);
				break;
			}

			if (array_type->eklass == REAL_T_MONOCLASS) {
				SET_FROM_ARRAY(PoolRealArray);
				break;
			}

			if (array_type->eklass == CACHED_CLASS_RAW(String)) {
				SET_FROM_ARRAY(PoolStringArray);
				break;
			}

			if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
				SET_FROM_ARRAY(PoolVector2Array);
				break;
			}

			if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
				SET_FROM_ARRAY(PoolVector3Array);
				break;
			}

			if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
				SET_FROM_ARRAY(PoolColorArray);
				break;
			}

			ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
			ERR_FAIL();
		} 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 *());
				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;
			}

			if (CACHED_CLASS(Dictionary) == type_class) {
				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
				mono_field_set_value(p_object, mono_field, managed);
				break;
			}

			if (CACHED_CLASS(Array) == type_class) {
				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
				mono_field_set_value(p_object, mono_field, managed);
				break;
			}

			ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name());
			ERR_FAIL();
		} break;

		case MONO_TYPE_OBJECT: {
			// Variant
			switch (p_value.get_type()) {
				case Variant::BOOL: {
					MonoBoolean val = p_value.operator bool();
					mono_field_set_value(p_object, mono_field, &val);
				} break;
				case Variant::INT: {
					int32_t val = p_value.operator signed int();
					mono_field_set_value(p_object, mono_field, &val);
				} break;
				case Variant::REAL: {
#ifdef REAL_T_IS_DOUBLE
					double val = p_value.operator double();
					mono_field_set_value(p_object, mono_field, &val);
#else
					float val = p_value.operator float();
					mono_field_set_value(p_object, mono_field, &val);
#endif
				} break;
				case Variant::STRING: {
					MonoString *mono_string = GDMonoMarshal::mono_string_from_godot(p_value);
					mono_field_set_value(p_object, mono_field, mono_string);
				} break;
				case Variant::VECTOR2: {
					SET_FROM_STRUCT(Vector2);
				} break;
				case Variant::RECT2: {
					SET_FROM_STRUCT(Rect2);
				} break;
				case Variant::VECTOR3: {
					SET_FROM_STRUCT(Vector3);
				} break;
				case Variant::TRANSFORM2D: {
					SET_FROM_STRUCT(Transform2D);
				} break;
				case Variant::PLANE: {
					SET_FROM_STRUCT(Plane);
				} break;
				case Variant::QUAT: {
					SET_FROM_STRUCT(Quat);
				} break;
				case Variant::AABB: {
					SET_FROM_STRUCT(AABB);
				} break;
				case Variant::BASIS: {
					SET_FROM_STRUCT(Basis);
				} break;
				case Variant::TRANSFORM: {
					SET_FROM_STRUCT(Transform);
				} break;
				case Variant::COLOR: {
					SET_FROM_STRUCT(Color);
				} break;
				case Variant::NODE_PATH: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath());
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::_RID: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID());
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::OBJECT: {
					MonoObject *managed = GDMonoUtils::unmanaged_get_managed(p_value.operator Object *());
					mono_field_set_value(p_object, mono_field, managed);
					break;
				}
				case Variant::DICTIONARY: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::ARRAY: {
					MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
					mono_field_set_value(p_object, mono_field, managed);
				} break;
				case Variant::POOL_BYTE_ARRAY: {
					SET_FROM_ARRAY(PoolByteArray);
				} break;
				case Variant::POOL_INT_ARRAY: {
					SET_FROM_ARRAY(PoolIntArray);
				} break;
				case Variant::POOL_REAL_ARRAY: {
					SET_FROM_ARRAY(PoolRealArray);
				} break;
				case Variant::POOL_STRING_ARRAY: {
					SET_FROM_ARRAY(PoolStringArray);
				} break;
				case Variant::POOL_VECTOR2_ARRAY: {
					SET_FROM_ARRAY(PoolVector2Array);
				} break;
				case Variant::POOL_VECTOR3_ARRAY: {
					SET_FROM_ARRAY(PoolVector3Array);
				} break;
				case Variant::POOL_COLOR_ARRAY: {
					SET_FROM_ARRAY(PoolColorArray);
				} break;
				default: break;
			}
		} break;

		case MONO_TYPE_GENERICINST: {
			MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type());

			MonoException *exc = NULL;

			GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType);
			MonoBoolean is_dict = type_is_dict((MonoObject *)reftype, (MonoObject **)&exc);
			UNLIKELY_UNHANDLED_EXCEPTION(exc);

			if (is_dict) {
				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
				mono_field_set_value(p_object, mono_field, managed);
				break;
			}

			exc = NULL;

			GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType);
			MonoBoolean is_array = type_is_array((MonoObject *)reftype, (MonoObject **)&exc);
			UNLIKELY_UNHANDLED_EXCEPTION(exc);

			if (is_array) {
				MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
				mono_field_set_value(p_object, mono_field, managed);
				break;
			}
		} break;

		default: {
			ERR_PRINTS(String() + "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
}
Exemplo n.º 16
0
Variant mono_object_to_variant(MonoObject *p_obj) {
	if (!p_obj)
		return Variant();

	GDMonoClass *tclass = GDMono::get_singleton()->get_class(mono_object_get_class(p_obj));
	ERR_FAIL_COND_V(!tclass, Variant());

	MonoType *raw_type = tclass->get_mono_type();

	ManagedType type;

	type.type_encoding = mono_type_get_type(raw_type);
	type.type_class = tclass;

	switch (type.type_encoding) {
		case MONO_TYPE_BOOLEAN:
			return (bool)unbox<MonoBoolean>(p_obj);

		case MONO_TYPE_I1:
			return unbox<int8_t>(p_obj);
		case MONO_TYPE_I2:
			return unbox<int16_t>(p_obj);
		case MONO_TYPE_I4:
			return unbox<int32_t>(p_obj);
		case MONO_TYPE_I8:
			return unbox<int64_t>(p_obj);

		case MONO_TYPE_U1:
			return unbox<uint8_t>(p_obj);
		case MONO_TYPE_U2:
			return unbox<uint16_t>(p_obj);
		case MONO_TYPE_U4:
			return unbox<uint32_t>(p_obj);
		case MONO_TYPE_U8:
			return unbox<uint64_t>(p_obj);

		case MONO_TYPE_R4:
			return unbox<float>(p_obj);
		case MONO_TYPE_R8:
			return unbox<double>(p_obj);

		case MONO_TYPE_STRING: {
			if (p_obj == NULL)
				return Variant(); // NIL
			return mono_string_to_godot_not_null((MonoString *)p_obj);
		} break;

		case MONO_TYPE_VALUETYPE: {
			GDMonoClass *tclass = type.type_class;

			if (tclass == CACHED_CLASS(Vector2))
				RETURN_UNBOXED_STRUCT(Vector2, p_obj);

			if (tclass == CACHED_CLASS(Rect2))
				RETURN_UNBOXED_STRUCT(Rect2, p_obj);

			if (tclass == CACHED_CLASS(Transform2D))
				RETURN_UNBOXED_STRUCT(Transform2D, p_obj);

			if (tclass == CACHED_CLASS(Vector3))
				RETURN_UNBOXED_STRUCT(Vector3, p_obj);

			if (tclass == CACHED_CLASS(Basis))
				RETURN_UNBOXED_STRUCT(Basis, p_obj);

			if (tclass == CACHED_CLASS(Quat))
				RETURN_UNBOXED_STRUCT(Quat, p_obj);

			if (tclass == CACHED_CLASS(Transform))
				RETURN_UNBOXED_STRUCT(Transform, p_obj);

			if (tclass == CACHED_CLASS(AABB))
				RETURN_UNBOXED_STRUCT(AABB, p_obj);

			if (tclass == CACHED_CLASS(Color))
				RETURN_UNBOXED_STRUCT(Color, p_obj);

			if (tclass == CACHED_CLASS(Plane))
				RETURN_UNBOXED_STRUCT(Plane, p_obj);

			if (mono_class_is_enum(tclass->get_mono_ptr()))
				return unbox<int32_t>(p_obj);
		} 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))
				return mono_array_to_Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
				return mono_array_to_PoolByteArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
				return mono_array_to_PoolIntArray((MonoArray *)p_obj);

			if (array_type->eklass == REAL_T_MONOCLASS)
				return mono_array_to_PoolRealArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(String))
				return mono_array_to_PoolStringArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
				return mono_array_to_PoolVector2Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
				return mono_array_to_PoolVector3Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Color))
				return mono_array_to_PoolColorArray((MonoArray *)p_obj);

			ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant.");
			ERR_FAIL_V(Variant());
		} break;

		case MONO_TYPE_CLASS: {
			GDMonoClass *type_class = type.type_class;

			// GodotObject
			if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
				Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj));
				return ptr ? Variant(ptr) : Variant();
			}

			if (CACHED_CLASS(NodePath) == type_class) {
				NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj));
				return ptr ? Variant(*ptr) : Variant();
			}

			if (CACHED_CLASS(RID) == type_class) {
				RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj));
				return ptr ? Variant(*ptr) : Variant();
			}

			if (CACHED_CLASS(Array) == type_class) {
				MonoException *exc = NULL;
				GDMonoUtils::Array_GetPtr get_ptr = CACHED_METHOD_THUNK(Array, GetPtr);
				Array *ptr = get_ptr(p_obj, (MonoObject **)&exc);
				UNLIKELY_UNHANDLED_EXCEPTION(exc);
				return ptr ? Variant(*ptr) : Variant();
			}

			if (CACHED_CLASS(Dictionary) == type_class) {
				MonoException *exc = NULL;
				GDMonoUtils::Dictionary_GetPtr get_ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr);
				Dictionary *ptr = get_ptr(p_obj, (MonoObject **)&exc);
				UNLIKELY_UNHANDLED_EXCEPTION(exc);
				return ptr ? Variant(*ptr) : Variant();
			}
		} break;

		case MONO_TYPE_GENERICINST: {
			MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type());

			MonoException *exc = NULL;

			GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType);
			MonoBoolean is_dict = type_is_dict((MonoObject *)reftype, (MonoObject **)&exc);
			UNLIKELY_UNHANDLED_EXCEPTION(exc);

			if (is_dict) {
				MonoException *exc = NULL;
				MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
				UNLIKELY_UNHANDLED_EXCEPTION(exc);
				return *unbox<Dictionary *>(ret);
			}

			exc = NULL;

			GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType);
			MonoBoolean is_array = type_is_array((MonoObject *)reftype, (MonoObject **)&exc);
			UNLIKELY_UNHANDLED_EXCEPTION(exc);

			if (is_array) {
				MonoException *exc = NULL;
				MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
				UNLIKELY_UNHANDLED_EXCEPTION(exc);
				return *unbox<Array *>(ret);
			}
		} break;
	}

	ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
				type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding));
	ERR_FAIL_V(Variant());
}
Exemplo n.º 17
0
void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags) {

	// TODO right now there is no way to stop the export process with an error

	ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized());
	ERR_FAIL_NULL(TOOLS_DOMAIN);
	ERR_FAIL_NULL(GDMono::get_singleton()->get_editor_tools_assembly());

	if (FileAccess::exists(GodotSharpDirs::get_project_sln_path())) {
		String build_config = p_debug ? "Debug" : "Release";

		String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata." + String(p_debug ? "debug" : "release"));
		Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path);
		ERR_FAIL_COND(metadata_err != OK);

		ERR_FAIL_COND(!_add_file(scripts_metadata_path, scripts_metadata_path));

		// Turn export features into defines
		Vector<String> godot_defines;
		for (Set<String>::Element *E = p_features.front(); E; E = E->next()) {
			godot_defines.push_back(E->get());
		}
		ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config, godot_defines));

		// Add dependency assemblies

		Map<String, String> dependencies;

		String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name");
		if (project_dll_name.empty()) {
			project_dll_name = "UnnamedProject";
		}

		String project_dll_src_dir = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config);
		String project_dll_src_path = project_dll_src_dir.plus_file(project_dll_name + ".dll");
		dependencies.insert(project_dll_name, project_dll_src_path);

		{
			MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain");
			ERR_FAIL_NULL(export_domain);
			_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);

			_GDMONO_SCOPE_DOMAIN_(export_domain);

			GDMonoAssembly *scripts_assembly = NULL;
			bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name,
					project_dll_src_path, &scripts_assembly, /* refonly: */ true);

			ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name);
			ERR_FAIL_COND(!load_success);

			Vector<String> search_dirs;
			GDMonoAssembly::fill_search_dirs(search_dirs, build_config);
			Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies);
			ERR_FAIL_COND(depend_error != OK);
		}

		for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) {
			String depend_src_path = E->value();
			String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file());
			ERR_FAIL_COND(!_add_file(depend_src_path, depend_dst_path));
		}
	}

	// Mono specific export template extras (data dir)

	GDMonoClass *export_class = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "GodotSharpExport");
	ERR_FAIL_NULL(export_class);
	GDMonoMethod *export_begin_method = export_class->get_method("_ExportBegin", 4);
	ERR_FAIL_NULL(export_begin_method);

	MonoArray *features = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_features.size());
	int i = 0;
	for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) {
		MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get());
		mono_array_set(features, MonoString *, i, boxed);
		i++;
	}

	MonoBoolean debug = p_debug;
	MonoString *path = GDMonoMarshal::mono_string_from_godot(p_path);
	uint32_t flags = p_flags;
	void *args[4] = { features, &debug, path, &flags };
	MonoException *exc = NULL;
	export_begin_method->invoke_raw(NULL, args, &exc);

	if (exc) {
		GDMonoUtils::debug_print_unhandled_exception(exc);
		ERR_FAIL();
	}
}
Exemplo n.º 18
0
Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
	switch (p_type.type_encoding) {
		case MONO_TYPE_BOOLEAN:
			return (bool)unbox<MonoBoolean>(p_obj);

		case MONO_TYPE_I1:
			return unbox<int8_t>(p_obj);
		case MONO_TYPE_I2:
			return unbox<int16_t>(p_obj);
		case MONO_TYPE_I4:
			return unbox<int32_t>(p_obj);
		case MONO_TYPE_I8:
			return unbox<int64_t>(p_obj);

		case MONO_TYPE_U1:
			return unbox<uint8_t>(p_obj);
		case MONO_TYPE_U2:
			return unbox<uint16_t>(p_obj);
		case MONO_TYPE_U4:
			return unbox<uint32_t>(p_obj);
		case MONO_TYPE_U8:
			return unbox<uint64_t>(p_obj);

		case MONO_TYPE_R4:
			return unbox<float>(p_obj);
		case MONO_TYPE_R8:
			return unbox<double>(p_obj);

		case MONO_TYPE_STRING: {
			String str = mono_string_to_godot((MonoString *)p_obj);
			return str;
		} break;

		case MONO_TYPE_VALUETYPE: {
			GDMonoClass *tclass = p_type.type_class;

			if (tclass == CACHED_CLASS(Vector2))
				RETURN_UNBOXED_STRUCT(Vector2, p_obj);

			if (tclass == CACHED_CLASS(Rect2))
				RETURN_UNBOXED_STRUCT(Rect2, p_obj);

			if (tclass == CACHED_CLASS(Transform2D))
				RETURN_UNBOXED_STRUCT(Transform2D, p_obj);

			if (tclass == CACHED_CLASS(Vector3))
				RETURN_UNBOXED_STRUCT(Vector3, p_obj);

			if (tclass == CACHED_CLASS(Basis))
				RETURN_UNBOXED_STRUCT(Basis, p_obj);

			if (tclass == CACHED_CLASS(Quat))
				RETURN_UNBOXED_STRUCT(Quat, p_obj);

			if (tclass == CACHED_CLASS(Transform))
				RETURN_UNBOXED_STRUCT(Transform, p_obj);

			if (tclass == CACHED_CLASS(Rect3))
				RETURN_UNBOXED_STRUCT(Rect3, p_obj);

			if (tclass == CACHED_CLASS(Color))
				RETURN_UNBOXED_STRUCT(Color, p_obj);

			if (tclass == CACHED_CLASS(Plane))
				RETURN_UNBOXED_STRUCT(Plane, p_obj);

			if (mono_class_is_enum(tclass->get_raw()))
				return unbox<int32_t>(p_obj);
		} break;

		case MONO_TYPE_ARRAY:
		case MONO_TYPE_SZARRAY: {
			MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(p_type.type_class));

			if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
				return mono_array_to_Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
				return mono_array_to_PoolByteArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
				return mono_array_to_PoolIntArray((MonoArray *)p_obj);

			if (array_type->eklass == REAL_T_MONOCLASS)
				return mono_array_to_PoolRealArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(String))
				return mono_array_to_PoolStringArray((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
				return mono_array_to_PoolVector2Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
				return mono_array_to_PoolVector3Array((MonoArray *)p_obj);

			if (array_type->eklass == CACHED_CLASS_RAW(Color))
				return mono_array_to_PoolColorArray((MonoArray *)p_obj);

			ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant.");
			ERR_FAIL_V(Variant());
		} break;

		case MONO_TYPE_CLASS: {
			GDMonoClass *type_class = p_type.type_class;

			// GodotObject
			if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
				Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj));
				return ptr ? Variant(ptr) : Variant();
			}

			if (CACHED_CLASS(NodePath) == type_class) {
				NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj));
				return ptr ? Variant(*ptr) : Variant();
			}

			if (CACHED_CLASS(RID) == type_class) {
				RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj));
				return ptr ? Variant(*ptr) : Variant();
			}
		} break;

		case MONO_TYPE_GENERICINST: {
			if (CACHED_RAW_MONO_CLASS(Dictionary) == p_type.type_class->get_raw()) {
				return mono_object_to_Dictionary(p_obj);
			}
		} break;
	}

	ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
				p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
	ERR_FAIL_V(Variant());
}
Exemplo n.º 19
0
MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) {
	switch (p_type.type_encoding) {
		case MONO_TYPE_BOOLEAN: {
			MonoBoolean val = p_var->operator bool();
			return BOX_BOOLEAN(val);
		}

		case MONO_TYPE_I1: {
			char val = p_var->operator signed char();
			return BOX_INT8(val);
		}
		case MONO_TYPE_I2: {
			short val = p_var->operator signed short();
			return BOX_INT16(val);
		}
		case MONO_TYPE_I4: {
			int val = p_var->operator signed int();
			return BOX_INT32(val);
		}
		case MONO_TYPE_I8: {
			int64_t val = p_var->operator int64_t();
			return BOX_INT64(val);
		}

		case MONO_TYPE_U1: {
			char val = p_var->operator unsigned char();
			return BOX_UINT8(val);
		}
		case MONO_TYPE_U2: {
			short val = p_var->operator unsigned short();
			return BOX_UINT16(val);
		}
		case MONO_TYPE_U4: {
			int val = p_var->operator unsigned int();
			return BOX_UINT32(val);
		}
		case MONO_TYPE_U8: {
			uint64_t val = p_var->operator uint64_t();
			return BOX_UINT64(val);
		}

		case MONO_TYPE_R4: {
			float val = p_var->operator float();
			return BOX_FLOAT(val);
		}
		case MONO_TYPE_R8: {
			double val = p_var->operator double();
			return BOX_DOUBLE(val);
		}

		case MONO_TYPE_STRING: {
			return (MonoObject *)mono_string_from_godot(p_var->operator String());
		} break;

		case MONO_TYPE_VALUETYPE: {
			GDMonoClass *tclass = p_type.type_class;

			if (tclass == CACHED_CLASS(Vector2))
				RETURN_BOXED_STRUCT(Vector2, p_var);

			if (tclass == CACHED_CLASS(Rect2))
				RETURN_BOXED_STRUCT(Rect2, p_var);

			if (tclass == CACHED_CLASS(Transform2D))
				RETURN_BOXED_STRUCT(Transform2D, p_var);

			if (tclass == CACHED_CLASS(Vector3))
				RETURN_BOXED_STRUCT(Vector3, p_var);

			if (tclass == CACHED_CLASS(Basis))
				RETURN_BOXED_STRUCT(Basis, p_var);

			if (tclass == CACHED_CLASS(Quat))
				RETURN_BOXED_STRUCT(Quat, p_var);

			if (tclass == CACHED_CLASS(Transform))
				RETURN_BOXED_STRUCT(Transform, p_var);

			if (tclass == CACHED_CLASS(Rect3))
				RETURN_BOXED_STRUCT(Rect3, p_var);

			if (tclass == CACHED_CLASS(Color))
				RETURN_BOXED_STRUCT(Color, p_var);

			if (tclass == CACHED_CLASS(Plane))
				RETURN_BOXED_STRUCT(Plane, p_var);

			if (mono_class_is_enum(tclass->get_raw())) {
				int val = p_var->operator signed int();
				return BOX_ENUM(tclass->get_raw(), val);
			}
		} break;

		case MONO_TYPE_ARRAY:
		case MONO_TYPE_SZARRAY: {
			MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(p_type.type_class));

			if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
				return (MonoObject *)Array_to_mono_array(p_var->operator Array());

			if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
				return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());

			if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
				return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());

			if (array_type->eklass == REAL_T_MONOCLASS)
				return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());

			if (array_type->eklass == CACHED_CLASS_RAW(String))
				return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());

			if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
				return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());

			if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
				return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());

			if (array_type->eklass == CACHED_CLASS_RAW(Color))
				return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());

			ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
			ERR_FAIL_V(NULL);
		} break;

		case MONO_TYPE_CLASS: {
			GDMonoClass *type_class = p_type.type_class;

			// GodotObject
			if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
				return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
			}

			if (CACHED_CLASS(NodePath) == type_class) {
				return GDMonoUtils::create_managed_from(p_var->operator NodePath());
			}

			if (CACHED_CLASS(RID) == type_class) {
				return GDMonoUtils::create_managed_from(p_var->operator RID());
			}
		} break;
		case MONO_TYPE_OBJECT: {
			// Variant
			switch (p_var->get_type()) {
				case Variant::BOOL: {
					MonoBoolean val = p_var->operator bool();
					return BOX_BOOLEAN(val);
				}
				case Variant::INT: {
					int val = p_var->operator signed int();
					return BOX_INT32(val);
				}
				case Variant::REAL: {
#ifdef REAL_T_IS_DOUBLE
					double val = p_var->operator double();
					return BOX_DOUBLE(val);
#else
					float val = p_var->operator float();
					return BOX_FLOAT(val);
#endif
				}
				case Variant::STRING:
					return (MonoObject *)mono_string_from_godot(p_var->operator String());
				case Variant::VECTOR2:
					RETURN_BOXED_STRUCT(Vector2, p_var);
				case Variant::RECT2:
					RETURN_BOXED_STRUCT(Rect2, p_var);
				case Variant::VECTOR3:
					RETURN_BOXED_STRUCT(Vector3, p_var);
				case Variant::TRANSFORM2D:
					RETURN_BOXED_STRUCT(Transform2D, p_var);
				case Variant::PLANE:
					RETURN_BOXED_STRUCT(Plane, p_var);
				case Variant::QUAT:
					RETURN_BOXED_STRUCT(Quat, p_var);
				case Variant::RECT3:
					RETURN_BOXED_STRUCT(Rect3, p_var);
				case Variant::BASIS:
					RETURN_BOXED_STRUCT(Basis, p_var);
				case Variant::TRANSFORM:
					RETURN_BOXED_STRUCT(Transform, p_var);
				case Variant::COLOR:
					RETURN_BOXED_STRUCT(Color, p_var);
				case Variant::NODE_PATH:
					return GDMonoUtils::create_managed_from(p_var->operator NodePath());
				case Variant::_RID:
					return GDMonoUtils::create_managed_from(p_var->operator RID());
				case Variant::OBJECT: {
					return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
				}
				case Variant::DICTIONARY:
					return Dictionary_to_mono_object(p_var->operator Dictionary());
				case Variant::ARRAY:
					return (MonoObject *)Array_to_mono_array(p_var->operator Array());
				case Variant::POOL_BYTE_ARRAY:
					return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());
				case Variant::POOL_INT_ARRAY:
					return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());
				case Variant::POOL_REAL_ARRAY:
					return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());
				case Variant::POOL_STRING_ARRAY:
					return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());
				case Variant::POOL_VECTOR2_ARRAY:
					return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());
				case Variant::POOL_VECTOR3_ARRAY:
					return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());
				case Variant::POOL_COLOR_ARRAY:
					return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
				default:
					return NULL;
			}
			break;
			case MONO_TYPE_GENERICINST: {
				if (CACHED_RAW_MONO_CLASS(Dictionary) == p_type.type_class->get_raw()) {
					return Dictionary_to_mono_object(p_var->operator Dictionary());
				}
			} break;
		} break;
	}

	ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" +
				p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
	ERR_FAIL_V(NULL);
}