diff options
author | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2021-09-12 19:50:13 +0200 |
---|---|---|
committer | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2022-08-22 03:35:59 +0200 |
commit | 5e37d073bb86492e8c415964ffd554a2fa08920d (patch) | |
tree | 1023544131f8117ac5b61d12bdc6b6f790513429 /modules/mono/mono_gd | |
parent | 9a51430441eecafbd07a7b9eb46967e2c3dd8b5d (diff) |
C#: Re-write GD and some other icalls as P/Invoke
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 18 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 3 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 57 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.h | 9 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_method.cpp | 10 |
6 files changed, 20 insertions, 83 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index b45b71aea7..bf387be4c8 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -442,14 +442,12 @@ bool GDMono::_are_api_assemblies_out_of_sync() { return out_of_sync; } -void godot_register_gd_icalls(); void godot_register_object_icalls(); void godot_register_scene_tree_icalls(); void godot_register_placeholder_icalls(); void GDMono::_register_internal_calls() { // Registers internal calls that were not generated. - godot_register_gd_icalls(); godot_register_object_icalls(); godot_register_scene_tree_icalls(); godot_register_placeholder_icalls(); @@ -987,6 +985,8 @@ Error GDMono::_load_scripts_domain() { Error GDMono::_unload_scripts_domain() { ERR_FAIL_NULL_V(scripts_domain, ERR_BUG); + CSharpLanguage::get_singleton()->_on_scripts_domain_about_to_unload(); + print_verbose("Mono: Finalizing scripts domain..."); if (mono_domain_get() != root_domain) { @@ -1040,8 +1040,6 @@ Error GDMono::_unload_scripts_domain() { Error GDMono::reload_scripts_domain() { ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG); - CSharpLanguage::get_singleton()->_on_scripts_domain_about_to_unload(); - if (scripts_domain) { Error domain_unload_err = _unload_scripts_domain(); ERR_FAIL_COND_V_MSG(domain_unload_err != OK, domain_unload_err, "Mono: Failed to unload scripts domain."); diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 08660e3701..54e49cf5f5 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -116,7 +116,6 @@ void CachedData::clear_godot_api_cache() { methodthunk_GodotObject_Dispose.nullify(); methodthunk_SignalAwaiter_SignalCallback.nullify(); - methodthunk_GodotTaskScheduler_Activate.nullify(); methodthunk_Delegate_Equals.nullify(); @@ -137,8 +136,6 @@ void CachedData::clear_godot_api_cache() { methodthunk_Marshaling_SetFieldValue.nullify(); methodthunk_MarshalUtils_TypeHasFlagsAttribute.nullify(); - - task_scheduler_handle = Ref<MonoGCHandleRef>(); } #define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) @@ -197,7 +194,6 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(GodotObject, Dispose, CACHED_CLASS(GodotObject)->get_method("Dispose", 0)); CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1)); - CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)); CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TrySerializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TrySerializeDelegateWithGCHandle", 2)); CACHE_METHOD_THUNK_AND_CHECK(DelegateUtils, TryDeserializeDelegateWithGCHandle, GODOT_API_CLASS(DelegateUtils)->get_method("TryDeserializeDelegateWithGCHandle", 2)); @@ -233,10 +229,16 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4)); #endif - // TODO Move to CSharpLanguage::init() and do handle disposal - MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); - GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); - cached_data.task_scheduler_handle = MonoGCHandleRef::create_strong(task_scheduler); + MonoException *exc = nullptr; + GDMono::get_singleton() + ->get_core_api_assembly() + ->get_class("Godot", "Dispatcher") + ->get_method("InitializeDefaultGodotTaskScheduler") + ->invoke(nullptr, &exc); + + if (exc) { + GDMonoUtils::debug_unhandled_exception(exc); + } cached_data.godot_api_cache_updated = true; } diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 0db32b5885..5876583260 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -90,7 +90,6 @@ struct CachedData { GDMonoMethodThunk<MonoObject *> methodthunk_GodotObject_Dispose; GDMonoMethodThunk<MonoObject *, MonoArray *> methodthunk_SignalAwaiter_SignalCallback; - GDMonoMethodThunk<MonoObject *> methodthunk_GodotTaskScheduler_Activate; GDMonoMethodThunkR<MonoBoolean, MonoObject *, MonoObject *> methodthunk_Delegate_Equals; @@ -114,8 +113,6 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeHasFlagsAttribute; - Ref<MonoGCHandleRef> task_scheduler_handle; - bool corlib_cache_updated; bool godot_api_cache_updated; diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index ef6a008a25..8828ec588b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -40,9 +40,7 @@ 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) { - if (p_type.type_encoding == MONO_TYPE_VOID) { - return Variant::NIL; - } + 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; @@ -137,59 +135,6 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj) { return mono_object_to_variant_impl(p_obj, /* fail_with_err: */ false); } -String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { - if (p_obj == nullptr) { - return String("null"); - } - - Variant var = GDMonoMarshal::mono_object_to_variant_no_err(p_obj); - - if (var.get_type() == Variant::NIL) { // `&& p_obj != nullptr` but omitted because always true - // Cannot convert MonoObject* to Variant; fallback to 'ToString()'. - MonoException *exc = nullptr; - MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc); - - if (exc) { - if (r_exc) { - *r_exc = exc; - } - return String(); - } - - return GDMonoMarshal::mono_string_to_godot(mono_str); - } else { - return var.operator String(); - } -} - -MonoArray *Array_to_mono_array(const Array &p_array) { - int length = p_array.size(); - MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 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) { - return ret; - } - int length = mono_array_length(p_array); - ret.resize(length); - - for (int i = 0; i < length; i++) { - MonoObject *elem = mono_array_get(p_array, MonoObject *, i); - ret[i] = mono_object_to_variant(elem); - } - - return ret; -} - MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) { const String *r = p_array.ptr(); int length = p_array.size(); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 16683de51a..fbe5795df5 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -88,15 +88,6 @@ _FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant *p_var) { Variant mono_object_to_variant(MonoObject *p_obj); Variant mono_object_to_variant_no_err(MonoObject *p_obj); -/// Tries to convert the MonoObject* to Variant and then convert the Variant to String. -/// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead. -String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc); - -// Array - -MonoArray *Array_to_mono_array(const Array &p_array); -Array mono_array_to_Array(MonoArray *p_array); - // PackedStringArray MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array); diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 04f6005338..97d3c82230 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -253,9 +253,13 @@ const MethodInfo &GDMonoMethod::get_method_info() { method_info.name = name; bool nil_is_variant = false; - method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); - if (method_info.return_val.type == Variant::NIL && nil_is_variant) { - method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + if (return_type.type_encoding == MONO_TYPE_VOID) { + method_info.return_val = PropertyInfo(Variant::NIL, ""); + } else { + method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); + if (method_info.return_val.type == Variant::NIL && nil_is_variant) { + method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } } Vector<StringName> names; |