diff options
Diffstat (limited to 'modules/mono/csharp_script.cpp')
-rw-r--r-- | modules/mono/csharp_script.cpp | 397 |
1 files changed, 101 insertions, 296 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b088271b18..772c705981 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -30,8 +30,6 @@ #include "csharp_script.h" -#include <mono/metadata/threads.h> -#include <mono/metadata/tokentype.h> #include <stdint.h> #include "core/config/project_settings.h" @@ -59,7 +57,6 @@ #include "godotsharp_dirs.h" #include "managed_callable.h" #include "mono_gd/gd_mono_cache.h" -#include "mono_gd/gd_mono_utils.h" #include "signal_awaiter_utils.h" #include "utils/macros.h" #include "utils/string_utils.h" @@ -107,8 +104,12 @@ Error CSharpLanguage::execute_file(const String &p_path) { return OK; } -extern void *godotsharp_pinvoke_funcs[164]; +extern void *godotsharp_pinvoke_funcs[176]; [[maybe_unused]] volatile void **do_not_strip_godotsharp_pinvoke_funcs; +#ifdef TOOLS_ENABLED +extern void *godotsharp_editor_pinvoke_funcs[32]; +[[maybe_unused]] volatile void **do_not_strip_godotsharp_editor_pinvoke_funcs; +#endif void CSharpLanguage::init() { #ifdef DEBUG_METHODS_ENABLED @@ -122,6 +123,9 @@ void CSharpLanguage::init() { // Hopefully this will be enough for all compilers. Otherwise we could use the printf on fake getenv trick. do_not_strip_godotsharp_pinvoke_funcs = (volatile void **)godotsharp_pinvoke_funcs; +#ifdef TOOLS_ENABLED + do_not_strip_godotsharp_editor_pinvoke_funcs = (volatile void **)godotsharp_editor_pinvoke_funcs; +#endif #if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) // Generate the bindings here, before loading assemblies. The Godot assemblies @@ -709,19 +713,14 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { } void CSharpLanguage::frame() { - if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != nullptr) { - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_FrameCallback.invoke(&exc); - if (exc) { - GDMonoUtils::debug_unhandled_exception(exc); - } + if (gdmono && gdmono->is_runtime_initialized() && GDMonoCache::godot_api_cache_updated) { + GDMonoCache::managed_callbacks.ScriptManagerBridge_FrameCallback(); } } void CSharpLanguage::reload_all_scripts() { #ifdef GD_MONO_HOT_RELOAD if (is_assembly_reloading_needed()) { - GD_MONO_SCOPE_THREAD_ATTACH; reload_assemblies(false); } #endif @@ -738,7 +737,6 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft #ifdef GD_MONO_HOT_RELOAD if (is_assembly_reloading_needed()) { - GD_MONO_SCOPE_THREAD_ATTACH; reload_assemblies(p_soft_reload); } #endif @@ -750,6 +748,8 @@ bool CSharpLanguage::is_assembly_reloading_needed() { return false; } +#warning TODO +#if 0 GDMonoAssembly *proj_assembly = gdmono->get_project_assembly(); String appname_safe = ProjectSettings::get_singleton()->get_safe_project_name(); @@ -777,6 +777,9 @@ bool CSharpLanguage::is_assembly_reloading_needed() { } return true; +#else + return false; +#endif } void CSharpLanguage::reload_assemblies(bool p_soft_reload) { @@ -812,7 +815,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); MonoException *exc = nullptr; - bool success = (bool)GDMonoCache::cached_data.methodthunk_DelegateUtils_TrySerializeDelegateWithGCHandle + bool success = (bool)GDMonoCache::managed_callbacks.methodthunk_DelegateUtils_TrySerializeDelegateWithGCHandle .invoke(managed_callable->delegate_handle, managed_serialized_data, &exc); @@ -1098,7 +1101,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { MonoDelegate *delegate = nullptr; MonoException *exc = nullptr; - bool success = (bool)GDMonoCache::cached_data.methodthunk_DelegateUtils_TryDeserializeDelegate.invoke(managed_serialized_data, &delegate, &exc); + bool success = (bool)GDMonoCache::managed_callbacks.methodthunk_DelegateUtils_TryDeserializeDelegate.invoke(managed_serialized_data, &delegate, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); @@ -1135,7 +1138,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { void *delegate = nullptr; MonoException *exc = nullptr; - bool success = (bool)GDMonoCache::cached_data.methodthunk_DelegateUtils_TryDeserializeDelegateWithGCHandle + bool success = (bool)GDMonoCache::managed_callbacks.methodthunk_DelegateUtils_TryDeserializeDelegateWithGCHandle .invoke(managed_serialized_data, &delegate, &exc); if (exc) { @@ -1179,22 +1182,6 @@ bool CSharpLanguage::overrides_external_editor() { } #endif -void CSharpLanguage::thread_enter() { -#if 0 - if (gdmono->is_runtime_initialized()) { - GDMonoUtils::attach_current_thread(); - } -#endif -} - -void CSharpLanguage::thread_exit() { -#if 0 - if (gdmono->is_runtime_initialized()) { - GDMonoUtils::detach_current_thread(); - } -#endif -} - bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) { // Not a parser error in our case, but it's still used for other type of errors if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { @@ -1241,27 +1228,16 @@ void CSharpLanguage::_on_scripts_domain_about_to_unload() { #ifdef TOOLS_ENABLED void CSharpLanguage::_editor_init_callback() { - register_editor_internal_calls(); - - // Initialize GodotSharpEditor - - MonoClass *editor_klass = mono_class_from_name( - GDMono::get_singleton()->get_tools_assembly()->get_image(), - "GodotTools", "GodotSharpEditor"); - CRASH_COND(editor_klass == nullptr); + // Load GodotTools and initialize GodotSharpEditor - MonoMethod *create_instance = mono_class_get_method_from_name(editor_klass, "InternalCreateInstance", 0); - CRASH_COND(create_instance == nullptr); - - MonoException *exc = nullptr; - MonoObject *ret = mono_runtime_invoke(create_instance, nullptr, nullptr, (MonoObject **)&exc); - UNHANDLED_EXCEPTION(exc); - - EditorPlugin *godotsharp_editor = *(EditorPlugin **)mono_object_unbox(ret); + Object *editor_plugin_obj = GDMono::get_singleton()->plugin_callbacks.LoadToolsAssemblyCallback( + GodotSharpDirs::get_data_editor_tools_dir().plus_file("GodotTools.dll").utf16()); + CRASH_COND(editor_plugin_obj == nullptr); + EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(editor_plugin_obj); CRASH_COND(godotsharp_editor == nullptr); - // Enable it as a plugin + // Add plugin to EditorNode and enable it EditorNode::add_editor_plugin(godotsharp_editor); ED_SHORTCUT("mono/build_solution", TTR("Build Solution"), KeyModifierMask::ALT | Key::B); godotsharp_editor->enable_plugin(); @@ -1328,15 +1304,8 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b ERR_FAIL_COND_V_MSG(!parent_is_object_class, false, "Type inherits from native type '" + type_name + "', so it can't be instantiated in object of type: '" + p_object->get_class() + "'."); - MonoException *exc = nullptr; GCHandleIntPtr strong_gchandle = - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_CreateManagedForGodotObjectBinding - .invoke(&type_name, p_object, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - return false; - } + GDMonoCache::managed_callbacks.ScriptManagerBridge_CreateManagedForGodotObjectBinding(&type_name, p_object); ERR_FAIL_NULL_V(strong_gchandle.value, false); @@ -1395,8 +1364,6 @@ void CSharpLanguage::_instance_binding_free_callback(void *, void *, void *p_bin return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there } - GD_MONO_ASSERT_THREAD_ATTACHED; - { MutexLock lock(csharp_lang->language_bind_mutex); @@ -1407,10 +1374,8 @@ void CSharpLanguage::_instance_binding_free_callback(void *, void *, void *p_bin if (script_binding.inited) { // Set the native instance field to IntPtr.Zero, if not yet garbage collected. // This is done to avoid trying to dispose the native instance from Dispose(bool). - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_SetGodotObjectPtr - .invoke(script_binding.gchandle.get_intptr(), nullptr, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_SetGodotObjectPtr( + script_binding.gchandle.get_intptr(), nullptr); script_binding.gchandle.release(); script_binding.inited = false; @@ -1442,8 +1407,6 @@ GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, if (p_reference) { // Refcount incremented if (refcount > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 - GD_MONO_SCOPE_THREAD_ATTACH; - // The reference count was increased after the managed side was the only one referencing our owner. // This means the owner is being referenced again by the unmanaged side, // so the owner must hold the managed side alive again to avoid it from being GCed. @@ -1455,10 +1418,8 @@ GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, GCHandleIntPtr new_gchandle; bool create_weak = false; - MonoException *exc = nullptr; - bool target_alive = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_SwapGCHandleForType - .invoke(old_gchandle, &new_gchandle, create_weak, &exc); - UNHANDLED_EXCEPTION(exc); + bool target_alive = GDMonoCache::managed_callbacks.ScriptManagerBridge_SwapGCHandleForType( + old_gchandle, &new_gchandle, create_weak); if (!target_alive) { return false; // Called after the managed side was collected, so nothing to do here @@ -1471,8 +1432,6 @@ GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, } else { // Refcount decremented if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 - GD_MONO_SCOPE_THREAD_ATTACH; - // If owner owner is no longer referenced by the unmanaged side, // the managed instance takes responsibility of deleting the owner when GCed. @@ -1483,10 +1442,8 @@ GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, GCHandleIntPtr new_gchandle; bool create_weak = true; - MonoException *exc = nullptr; - bool target_alive = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_SwapGCHandleForType - .invoke(old_gchandle, &new_gchandle, create_weak, &exc); - UNHANDLED_EXCEPTION(exc); + bool target_alive = GDMonoCache::managed_callbacks.ScriptManagerBridge_SwapGCHandleForType( + old_gchandle, &new_gchandle, create_weak); if (!target_alive) { return refcount == 0; // Called after the managed side was collected, so nothing to do here @@ -1668,35 +1625,19 @@ Object *CSharpInstance::get_owner() { bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!script.is_valid(), false); - GD_MONO_SCOPE_THREAD_ATTACH; - - MonoException *exc = nullptr; - bool ret = GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Set.invoke( - gchandle.get_intptr(), &p_name, &p_value, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } else if (ret) { - return true; - } - - return false; + return GDMonoCache::managed_callbacks.CSharpInstanceBridge_Set( + gchandle.get_intptr(), &p_name, &p_value); } bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const { ERR_FAIL_COND_V(!script.is_valid(), false); - GD_MONO_SCOPE_THREAD_ATTACH; - Variant ret_value; - MonoException *exc = nullptr; - bool ret = GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Get.invoke( - gchandle.get_intptr(), &p_name, &ret_value, &exc); + bool ret = GDMonoCache::managed_callbacks.CSharpInstanceBridge_Get( + gchandle.get_intptr(), &p_name, &ret_value); - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } else if (ret) { + if (ret) { r_ret = ret_value; return true; } @@ -1756,7 +1697,7 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); MonoException *exc = nullptr; - bool success = (bool)GDMonoCache::cached_data.methodthunk_DelegateUtils_TrySerializeDelegate + bool success = (bool)GDMonoCache::managed_callbacks.methodthunk_DelegateUtils_TrySerializeDelegate .invoke(delegate_field_value, managed_serialized_data, &exc); if (exc) { @@ -1781,26 +1722,25 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { ERR_FAIL_COND(!script.is_valid()); - GD_MONO_SCOPE_THREAD_ATTACH; - StringName method = SNAME("_get_property_list"); Variant ret; Callable::CallError call_error; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Call.invoke( - gchandle.get_intptr(), &method, nullptr, 0, &call_error, &ret, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } - - ERR_FAIL_COND_MSG(call_error.error != Callable::CallError::CALL_OK, - "Error calling '_get_property_list': " + Variant::get_call_error_text(method, nullptr, 0, call_error)); - - Array array = ret; - for (int i = 0, size = array.size(); i < size; i++) { - p_properties->push_back(PropertyInfo::from_dict(array.get(i))); + bool ok = GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call( + gchandle.get_intptr(), &method, nullptr, 0, &call_error, &ret); + + // CALL_ERROR_INVALID_METHOD would simply mean it was not overridden + if (call_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD) { + if (call_error.error != Callable::CallError::CALL_OK) { + ERR_PRINT("Error calling '_get_property_list': " + Variant::get_call_error_text(method, nullptr, 0, call_error)); + } else if (!ok) { + ERR_PRINT("Unexpected error calling '_get_property_list'"); + } else { + Array array = ret; + for (int i = 0, size = array.size(); i < size; i++) { + p_properties->push_back(PropertyInfo::from_dict(array.get(i))); + } + } } for (const PropertyInfo &prop : props) { @@ -1826,22 +1766,13 @@ Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool * bool CSharpInstance::property_can_revert(const StringName &p_name) const { ERR_FAIL_COND_V(!script.is_valid(), false); - GD_MONO_SCOPE_THREAD_ATTACH; - - Callable::CallError call_error; - Variant name_arg = p_name; const Variant *args[1] = { &name_arg }; Variant ret; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Call.invoke( - gchandle.get_intptr(), &CACHED_STRING_NAME(_property_can_revert), args, 1, &call_error, &ret, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - return false; - } + Callable::CallError call_error; + GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call( + gchandle.get_intptr(), &CACHED_STRING_NAME(_property_can_revert), args, 1, &call_error, &ret); if (call_error.error != Callable::CallError::CALL_OK) { return false; @@ -1853,22 +1784,13 @@ bool CSharpInstance::property_can_revert(const StringName &p_name) const { bool CSharpInstance::property_get_revert(const StringName &p_name, Variant &r_ret) const { ERR_FAIL_COND_V(!script.is_valid(), false); - GD_MONO_SCOPE_THREAD_ATTACH; - - Callable::CallError call_error; - Variant name_arg = p_name; const Variant *args[1] = { &name_arg }; Variant ret; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Call.invoke( - gchandle.get_intptr(), &CACHED_STRING_NAME(_property_get_revert), args, 1, &call_error, &ret, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - return false; - } + Callable::CallError call_error; + GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call( + gchandle.get_intptr(), &CACHED_STRING_NAME(_property_get_revert), args, 1, &call_error, &ret); if (call_error.error != Callable::CallError::CALL_OK) { return false; @@ -1909,36 +1831,23 @@ bool CSharpInstance::has_method(const StringName &p_method) const { return false; } - GD_MONO_SCOPE_THREAD_ATTACH; - - if (!GDMonoCache::cached_data.godot_api_cache_updated) { + if (!GDMonoCache::godot_api_cache_updated) { return false; } String method = p_method; bool deep = true; - MonoException *exc = nullptr; - bool found = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_HasMethodUnknownParams - .invoke(script.ptr(), &method, deep, &exc); - UNHANDLED_EXCEPTION(exc); - - return found; + return GDMonoCache::managed_callbacks.ScriptManagerBridge_HasMethodUnknownParams( + script.ptr(), &method, deep); } Variant CSharpInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { ERR_FAIL_COND_V(!script.is_valid(), Variant()); - GD_MONO_SCOPE_THREAD_ATTACH; - Variant ret; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Call.invoke( - gchandle.get_intptr(), &p_method, p_args, p_argcount, &r_error, &ret, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call( + gchandle.get_intptr(), &p_method, p_args, p_argcount, &r_error, &ret); return ret; } @@ -1992,13 +1901,10 @@ bool CSharpInstance::_internal_new_managed() { ERR_FAIL_NULL_V(owner, false); ERR_FAIL_COND_V(script.is_null(), false); - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_CreateManagedForGodotObjectScriptInstance - .invoke(script.ptr(), owner, nullptr, 0, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); + bool ok = GDMonoCache::managed_callbacks.ScriptManagerBridge_CreateManagedForGodotObjectScriptInstance( + script.ptr(), owner, nullptr, 0); + if (!ok) { // Important to clear this before destroying the script instance here script = Ref<CSharpScript>(); owner = nullptr; @@ -2084,8 +1990,6 @@ void CSharpInstance::refcount_incremented() { RefCounted *rc_owner = Object::cast_to<RefCounted>(owner); if (rc_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 - GD_MONO_SCOPE_THREAD_ATTACH; - // The reference count was increased after the managed side was the only one referencing our owner. // This means the owner is being referenced again by the unmanaged side, // so the owner must hold the managed side alive again to avoid it from being GCed. @@ -2097,10 +2001,8 @@ void CSharpInstance::refcount_incremented() { GCHandleIntPtr new_gchandle; bool create_weak = false; - MonoException *exc = nullptr; - bool target_alive = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_SwapGCHandleForType - .invoke(old_gchandle, &new_gchandle, create_weak, &exc); - UNHANDLED_EXCEPTION(exc); + bool target_alive = GDMonoCache::managed_callbacks.ScriptManagerBridge_SwapGCHandleForType( + old_gchandle, &new_gchandle, create_weak); if (!target_alive) { return; // Called after the managed side was collected, so nothing to do here @@ -2121,8 +2023,6 @@ bool CSharpInstance::refcount_decremented() { int refcount = rc_owner->reference_get_count(); if (refcount == 1 && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 - GD_MONO_SCOPE_THREAD_ATTACH; - // If owner owner is no longer referenced by the unmanaged side, // the managed instance takes responsibility of deleting the owner when GCed. @@ -2133,10 +2033,8 @@ bool CSharpInstance::refcount_decremented() { GCHandleIntPtr new_gchandle; bool create_weak = true; - MonoException *exc = nullptr; - bool target_alive = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_SwapGCHandleForType - .invoke(old_gchandle, &new_gchandle, create_weak, &exc); - UNHANDLED_EXCEPTION(exc); + bool target_alive = GDMonoCache::managed_callbacks.ScriptManagerBridge_SwapGCHandleForType( + old_gchandle, &new_gchandle, create_weak); if (!target_alive) { return refcount == 0; // Called after the managed side was collected, so nothing to do here @@ -2157,8 +2055,6 @@ const Variant CSharpInstance::get_rpc_config() const { } void CSharpInstance::notification(int p_notification) { - GD_MONO_SCOPE_THREAD_ATTACH; - if (p_notification == Object::NOTIFICATION_PREDELETE) { // When NOTIFICATION_PREDELETE is sent, we also take the chance to call Dispose(). // It's safe to call Dispose() multiple times and NOTIFICATION_PREDELETE is guaranteed @@ -2178,13 +2074,8 @@ void CSharpInstance::notification(int p_notification) { _call_notification(p_notification); - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_CallDispose - .invoke(gchandle.get_intptr(), /* okIfNull */ false, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_CallDispose( + gchandle.get_intptr(), /* okIfNull */ false); return; } @@ -2193,8 +2084,6 @@ void CSharpInstance::notification(int p_notification) { } void CSharpInstance::_call_notification(int p_notification) { - GD_MONO_ASSERT_THREAD_ATTACHED; - Variant arg = p_notification; const Variant *args[1] = { &arg }; StringName method_name = SNAME("_notification"); @@ -2202,32 +2091,16 @@ void CSharpInstance::_call_notification(int p_notification) { Callable::CallError call_error; Variant ret; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_Call.invoke( - gchandle.get_intptr(), &method_name, args, 1, &call_error, &ret, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_Call( + gchandle.get_intptr(), &method_name, args, 1, &call_error, &ret); } String CSharpInstance::to_string(bool *r_valid) { - GD_MONO_SCOPE_THREAD_ATTACH; - String res; bool valid; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_CallToString - .invoke(gchandle.get_intptr(), &res, &valid, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - if (r_valid) { - *r_valid = false; - } - return String(); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_CallToString( + gchandle.get_intptr(), &res, &valid); if (r_valid) { *r_valid = valid; @@ -2249,8 +2122,6 @@ CSharpInstance::CSharpInstance(const Ref<CSharpScript> &p_script) : } CSharpInstance::~CSharpInstance() { - GD_MONO_SCOPE_THREAD_ATTACH; - destructing_script_instance = true; // Must make sure event signals are not left dangling @@ -2264,13 +2135,8 @@ CSharpInstance::~CSharpInstance() { // we must call Dispose here, because Dispose calls owner->set_script_instance(nullptr) // and that would mess up with the new script instance if called later. - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_CallDispose - .invoke(gchandle.get_intptr(), /* okIfNull */ true, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_CallDispose( + gchandle.get_intptr(), /* okIfNull */ true); } gchandle.release(); // Make sure the gchandle is released @@ -2341,8 +2207,6 @@ void CSharpScript::_update_exports_values(HashMap<StringName, Variant> &values, void CSharpScript::_update_member_info_no_exports() { if (exports_invalidated) { - GD_MONO_ASSERT_THREAD_ATTACHED; - exports_invalidated = false; member_info.clear(); @@ -2888,10 +2752,8 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { // only for this, so need to call the destructor manually before passing this to C#. rpc_functions_dict.~Dictionary(); - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_UpdateScriptClassInfo - .invoke(p_script.ptr(), &tool, &rpc_functions_dict, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_UpdateScriptClassInfo( + p_script.ptr(), &tool, &rpc_functions_dict); p_script->tool = tool; @@ -2910,13 +2772,7 @@ bool CSharpScript::can_instantiate() const { // For tool scripts, this will never fire if the class is not found. That's because we // don't know if it's a tool script if we can't find the class to access the attributes. if (extra_cond && !valid) { - if (GDMono::get_singleton()->get_project_assembly() == nullptr) { - // The project assembly is not loaded - ERR_FAIL_V_MSG(false, "Cannot instance script because the project assembly is not loaded. Script: '" + get_path() + "'."); - } else { - // The project assembly is loaded, but the class could not found - ERR_FAIL_V_MSG(false, "Cannot instance script because the associated class could not be found. Script: '" + get_path() + "'."); - } + ERR_FAIL_V_MSG(false, "Cannot instance script because the associated class could not be found. Script: '" + get_path() + "'."); } return valid && extra_cond; @@ -2924,16 +2780,11 @@ bool CSharpScript::can_instantiate() const { StringName CSharpScript::get_instance_base_type() const { StringName native_name; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_GetScriptNativeName - .invoke(this, &native_name, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_GetScriptNativeName(this, &native_name); return native_name; } CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_is_ref_counted, Callable::CallError &r_error) { - GD_MONO_ASSERT_THREAD_ATTACHED; - /* STEP 1, CREATE */ Ref<RefCounted> ref; @@ -2949,13 +2800,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)data)->get(); if (script_binding.inited && !script_binding.gchandle.is_released()) { - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_CSharpInstanceBridge_CallDispose - .invoke(script_binding.gchandle.get_intptr(), /* okIfNull */ true, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); - } + GDMonoCache::managed_callbacks.CSharpInstanceBridge_CallDispose( + script_binding.gchandle.get_intptr(), /* okIfNull */ true); script_binding.gchandle.release(); // Just in case script_binding.inited = false; @@ -2969,13 +2815,10 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg /* STEP 2, INITIALIZE AND CONSTRUCT */ - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_CreateManagedForGodotObjectScriptInstance - .invoke(this, p_owner, p_args, p_argcount, &exc); - - if (exc) { - GDMonoUtils::set_pending_exception(exc); + bool ok = GDMonoCache::managed_callbacks.ScriptManagerBridge_CreateManagedForGodotObjectScriptInstance( + this, p_owner, p_args, p_argcount); + if (!ok) { // Important to clear this before destroying the script instance here instance->script = Ref<CSharpScript>(); instance->owner = nullptr; @@ -3001,15 +2844,10 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Callable::Cal r_error.error = Callable::CallError::CALL_OK; StringName native_name; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_GetScriptNativeName - .invoke(this, &native_name, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_GetScriptNativeName(this, &native_name); ERR_FAIL_COND_V(native_name == StringName(), Variant()); - GD_MONO_SCOPE_THREAD_ATTACH; - Object *owner = ClassDB::instantiate(native_name); Ref<RefCounted> ref; @@ -3038,13 +2876,8 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { CRASH_COND(!valid); #endif - GD_MONO_SCOPE_THREAD_ATTACH; - StringName native_name; - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_GetScriptNativeName - .invoke(this, &native_name, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_GetScriptNativeName(this, &native_name); ERR_FAIL_COND_V(native_name == StringName(), nullptr); @@ -3100,8 +2933,6 @@ void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const { return; } - GD_MONO_SCOPE_THREAD_ATTACH; - #warning TODO #if 0 // TODO: We're filtering out constructors but there may be other methods unsuitable for explicit calls. @@ -3126,19 +2957,15 @@ bool CSharpScript::has_method(const StringName &p_method) const { return false; } - GD_MONO_SCOPE_THREAD_ATTACH; - - if (!GDMonoCache::cached_data.godot_api_cache_updated) { + if (!GDMonoCache::godot_api_cache_updated) { return false; } String method = p_method; bool deep = false; - MonoException *exc = nullptr; - bool found = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_HasMethodUnknownParams - .invoke(this, &method, deep, &exc); - UNHANDLED_EXCEPTION(exc); + bool found = GDMonoCache::managed_callbacks.ScriptManagerBridge_HasMethodUnknownParams( + this, &method, deep); return found; } @@ -3148,8 +2975,6 @@ MethodInfo CSharpScript::get_method_info(const StringName &p_method) const { return MethodInfo(); } - GD_MONO_SCOPE_THREAD_ATTACH; - #warning TODO #if 0 GDMonoClass *top = script_class; @@ -3176,14 +3001,9 @@ Error CSharpScript::reload(bool p_keep_state) { // That's done separately via domain reloading. reload_invalidated = false; - GD_MONO_SCOPE_THREAD_ATTACH; - String script_path = get_path(); - MonoException *exc = nullptr; - valid = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_AddScriptBridge - .invoke(this, &script_path, &exc); - UNHANDLED_EXCEPTION(exc); + valid = GDMonoCache::managed_callbacks.ScriptManagerBridge_AddScriptBridge(this, &script_path); if (valid) { #ifdef DEBUG_ENABLED @@ -3230,18 +3050,13 @@ bool CSharpScript::has_script_signal(const StringName &p_signal) const { return false; } - if (!GDMonoCache::cached_data.godot_api_cache_updated) { + if (!GDMonoCache::godot_api_cache_updated) { return false; } String signal = p_signal; - MonoException *exc = nullptr; - bool res = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_HasScriptSignal - .invoke(this, &signal, &exc); - UNHANDLED_EXCEPTION(exc); - - return res; + return GDMonoCache::managed_callbacks.ScriptManagerBridge_HasScriptSignal(this, &signal); } void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { @@ -3251,7 +3066,7 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { // Performance is not critical here as this will be replaced with source generators. - if (!GDMonoCache::cached_data.godot_api_cache_updated) { + if (!GDMonoCache::godot_api_cache_updated) { return; } @@ -3260,10 +3075,7 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { // only for this, so need to call the destructor manually before passing this to C#. signals_dict.~Dictionary(); - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_GetScriptSignalList - .invoke(this, &signals_dict, &exc); - UNHANDLED_EXCEPTION(exc); + GDMonoCache::managed_callbacks.ScriptManagerBridge_GetScriptSignalList(this, &signals_dict); for (const Variant *s = signals_dict.next(nullptr); s != nullptr; s = signals_dict.next(s)) { MethodInfo mi; @@ -3296,16 +3108,11 @@ bool CSharpScript::inherits_script(const Ref<Script> &p_script) const { return false; } - if (!GDMonoCache::cached_data.godot_api_cache_updated) { + if (!GDMonoCache::godot_api_cache_updated) { return false; } - MonoException *exc = nullptr; - bool res = GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_ScriptIsOrInherits - .invoke(this, cs.ptr(), &exc); - UNHANDLED_EXCEPTION(exc); - - return res; + return GDMonoCache::managed_callbacks.ScriptManagerBridge_ScriptIsOrInherits(this, cs.ptr()); } Ref<Script> CSharpScript::get_base_script() const { @@ -3379,10 +3186,8 @@ CSharpScript::~CSharpScript() { CSharpLanguage::get_singleton()->script_list.remove(&this->script_list); #endif - if (GDMonoCache::cached_data.godot_api_cache_updated) { - MonoException *exc = nullptr; - GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_RemoveScriptBridge.invoke(this, &exc); - UNHANDLED_EXCEPTION(exc); + if (GDMonoCache::godot_api_cache_updated) { + GDMonoCache::managed_callbacks.ScriptManagerBridge_RemoveScriptBridge(this); } } |