/*************************************************************************/ /* gd_mono_marshal.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "gd_mono_marshal.h" #include "../signal_awaiter_utils.h" #include "gd_mono.h" #include "gd_mono_cache.h" #include "gd_mono_class.h" namespace GDMonoMarshal { // TODO: Those are just temporary until the code that needs them is moved to C# Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant) { CRASH_COND(p_type.type_class == nullptr); MonoReflectionType *refltype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); MonoBoolean nil_is_variant = false; MonoException *exc = nullptr; int32_t ret = CACHED_METHOD_THUNK(Marshaling, managed_to_variant_type) .invoke(refltype, &nil_is_variant, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); return Variant::NIL; } if (r_nil_is_variant) { *r_nil_is_variant = (bool)nil_is_variant; } return (Variant::Type)ret; } bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) { MonoReflectionType *array_refltype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type()); MonoReflectionType *elem_refltype = nullptr; MonoException *exc = nullptr; MonoBoolean ret = CACHED_METHOD_THUNK(Marshaling, try_get_array_element_type) .invoke(array_refltype, &elem_refltype, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); return Variant::NIL; } r_elem_type = ManagedType::from_reftype(elem_refltype); return ret; } MonoObject *variant_to_mono_object_of_type(const Variant &p_var, const ManagedType &p_type) { MonoReflectionType *refltype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); MonoException *exc = nullptr; MonoObject *ret = CACHED_METHOD_THUNK(Marshaling, variant_to_mono_object_of_type) .invoke(&p_var, refltype, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); return nullptr; } return ret; } MonoObject *variant_to_mono_object(const Variant &p_var) { MonoException *exc = nullptr; MonoObject *ret = CACHED_METHOD_THUNK(Marshaling, variant_to_mono_object) .invoke(&p_var, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); return nullptr; } return ret; } static Variant mono_object_to_variant_impl(MonoObject *p_obj, bool p_fail_with_err) { if (!p_obj) { return Variant(); } MonoBoolean fail_with_error = p_fail_with_err; Variant ret; MonoException *exc = nullptr; CACHED_METHOD_THUNK(Marshaling, mono_object_to_variant_out) .invoke(p_obj, fail_with_error, &ret, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); return Variant(); } return ret; } Variant mono_object_to_variant(MonoObject *p_obj) { return mono_object_to_variant_impl(p_obj, /* fail_with_err: */ true); } Variant mono_object_to_variant_no_err(MonoObject *p_obj) { return mono_object_to_variant_impl(p_obj, /* fail_with_err: */ false); } MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) { const String *r = p_array.ptr(); int length = p_array.size(); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), length); for (int i = 0; i < length; i++) { MonoString *boxed = mono_string_from_godot(r[i]); mono_array_setref(ret, i, boxed); } return ret; } } // namespace GDMonoMarshal