summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2021-09-12 19:50:13 +0200
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:35:59 +0200
commit5e37d073bb86492e8c415964ffd554a2fa08920d (patch)
tree1023544131f8117ac5b61d12bdc6b6f790513429 /modules/mono/mono_gd
parent9a51430441eecafbd07a7b9eb46967e2c3dd8b5d (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.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h3
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp57
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h9
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp10
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;