summaryrefslogtreecommitdiff
path: root/modules/mono/csharp_script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/csharp_script.cpp')
-rw-r--r--modules/mono/csharp_script.cpp397
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);
}
}