summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd/gd_mono.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/mono_gd/gd_mono.cpp')
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp446
1 files changed, 42 insertions, 404 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index bf387be4c8..ce4fc0c5a0 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -48,8 +48,6 @@
#include "../godotsharp_dirs.h"
#include "../utils/path_utils.h"
#include "gd_mono_cache.h"
-#include "gd_mono_class.h"
-#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
#ifdef ANDROID_ENABLED
@@ -411,7 +409,9 @@ void GDMono::initialize_load_assemblies() {
// Load assemblies. The API and tools assemblies are required,
// the application is aborted if these assemblies cannot be loaded.
- _load_api_assemblies();
+ if (!_try_load_api_assemblies()) {
+ CRASH_NOW_MSG("Failed to load one of the API assemblies.");
+ }
#if defined(TOOLS_ENABLED)
bool tool_assemblies_loaded = _load_tools_assemblies();
@@ -432,24 +432,12 @@ void GDMono::initialize_load_assemblies() {
}
}
-bool GDMono::_are_api_assemblies_out_of_sync() {
- bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated);
-#ifdef TOOLS_ENABLED
- if (!out_of_sync) {
- out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync;
- }
-#endif
- return out_of_sync;
-}
-
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_object_icalls();
- godot_register_scene_tree_icalls();
godot_register_placeholder_icalls();
}
@@ -490,35 +478,35 @@ GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
return result ? *result : nullptr;
}
-bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly) {
+bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly) {
#ifdef DEBUG_ENABLED
CRASH_COND(!r_assembly);
#endif
MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
- bool result = load_assembly(p_name, aname, r_assembly, p_refonly);
+ bool result = load_assembly(p_name, aname, r_assembly);
mono_assembly_name_free(aname);
mono_free(aname);
return result;
}
-bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) {
+bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly) {
#ifdef DEBUG_ENABLED
CRASH_COND(!r_assembly);
#endif
- return load_assembly(p_name, p_aname, r_assembly, p_refonly, GDMonoAssembly::get_default_search_dirs());
+ return load_assembly(p_name, p_aname, r_assembly, GDMonoAssembly::get_default_search_dirs());
}
-bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly, const Vector<String> &p_search_dirs) {
+bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, const Vector<String> &p_search_dirs) {
#ifdef DEBUG_ENABLED
CRASH_COND(!r_assembly);
#endif
- print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
+ print_verbose("Mono: Loading assembly " + p_name + "...");
- GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs);
+ GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, /* refonly: */ false, p_search_dirs);
if (!assembly) {
return false;
@@ -526,17 +514,17 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
*r_assembly = assembly;
- print_verbose("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path());
+ print_verbose("Mono: Assembly " + p_name + " loaded from path: " + (*r_assembly)->get_path());
return true;
}
-bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly, bool p_refonly) {
+bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly) {
CRASH_COND(!r_assembly);
- print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
+ print_verbose("Mono: Loading assembly " + p_name + "...");
- GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly);
+ GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, /* refonly: */ false);
if (!assembly) {
return false;
@@ -544,279 +532,41 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo
*r_assembly = assembly;
- print_verbose("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path());
+ print_verbose("Mono: Assembly " + p_name + " loaded from path: " + (*r_assembly)->get_path());
return true;
}
-ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, ApiAssemblyInfo::Type p_api_type) {
- ApiAssemblyInfo::Version api_assembly_version;
-
- const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE
- ? BINDINGS_CLASS_NATIVECALLS
- : BINDINGS_CLASS_NATIVECALLS_EDITOR;
-
- GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name);
-
- if (nativecalls_klass) {
- GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash");
- if (api_hash_field) {
- api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr));
- }
- }
-
- return api_assembly_version;
-}
-
-String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) {
- return p_type == ApiAssemblyInfo::API_CORE ? "API_CORE" : "API_EDITOR";
-}
-
bool GDMono::_load_corlib_assembly() {
if (corlib_assembly) {
return true;
}
- bool success = load_assembly("mscorlib", &corlib_assembly);
-
- if (success) {
- GDMonoCache::update_corlib_cache();
- }
-
- return success;
-}
-
-#ifdef TOOLS_ENABLED
-bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config) {
- String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
- String dst_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
-
- String assembly_name = p_api_type == ApiAssemblyInfo::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME;
-
- // Create destination directory if needed
- if (!DirAccess::exists(dst_dir)) {
- Ref<DirAccess> da = DirAccess::create_for_path(dst_dir);
- Error err = da->make_dir_recursive(dst_dir);
-
- if (err != OK) {
- ERR_PRINT("Failed to create destination directory for the API assemblies. Error: " + itos(err) + ".");
- return false;
- }
- }
-
- Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
-
- String xml_file = assembly_name + ".xml";
- if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) {
- WARN_PRINT("Failed to copy '" + xml_file + "'.");
- }
-
- String pdb_file = assembly_name + ".pdb";
- if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) {
- WARN_PRINT("Failed to copy '" + pdb_file + "'.");
- }
-
- String assembly_file = assembly_name + ".dll";
- if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) {
- ERR_PRINT("Failed to copy '" + assembly_file + "'.");
- return false;
- }
-
- return true;
-}
-
-static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool &r_out_of_sync) {
- String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
-
- if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) {
- return false;
- }
-
- String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg");
-
- if (!FileAccess::exists(cached_api_hash_path)) {
- return false;
- }
-
- Ref<ConfigFile> cfg;
- cfg.instantiate();
- Error cfg_err = cfg->load(cached_api_hash_path);
- ERR_FAIL_COND_V(cfg_err != OK, false);
-
- // Checking the modified time is good enough
- if (FileAccess::get_modified_time(core_api_assembly_path) != (uint64_t)cfg->get_value("core", "modified_time") ||
- FileAccess::get_modified_time(editor_api_assembly_path) != (uint64_t)cfg->get_value("editor", "modified_time")) {
- return false;
- }
-
- r_out_of_sync = GDMono::get_singleton()->get_api_core_hash() != (uint64_t)cfg->get_value("core", "api_hash") ||
- GDMono::get_singleton()->get_api_editor_hash() != (uint64_t)cfg->get_value("editor", "api_hash");
-
- return true;
-}
-
-static void create_cached_api_hash_for(const String &p_api_assemblies_dir) {
- String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
- String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg");
-
- Ref<ConfigFile> cfg;
- cfg.instantiate();
-
- cfg->set_value("core", "modified_time", FileAccess::get_modified_time(core_api_assembly_path));
- cfg->set_value("editor", "modified_time", FileAccess::get_modified_time(editor_api_assembly_path));
-
- // This assumes the prebuilt api assemblies we copied to the project are not out of sync
- cfg->set_value("core", "api_hash", GDMono::get_singleton()->get_api_core_hash());
- cfg->set_value("editor", "api_hash", GDMono::get_singleton()->get_api_editor_hash());
-
- Error err = cfg->save(cached_api_hash_path);
- ERR_FAIL_COND(err != OK);
-}
-
-bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config) {
- MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.Domain.CheckApiAssemblies");
- ERR_FAIL_NULL_V(temp_domain, "Failed to create temporary domain to check API assemblies");
- _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(temp_domain);
-
- _GDMONO_SCOPE_DOMAIN_(temp_domain);
-
- GDMono::LoadedApiAssembly temp_core_api_assembly;
- GDMono::LoadedApiAssembly temp_editor_api_assembly;
-
- if (!_try_load_api_assemblies(temp_core_api_assembly, temp_editor_api_assembly,
- p_config, /* refonly: */ true, /* loaded_callback: */ nullptr)) {
- return temp_core_api_assembly.out_of_sync || temp_editor_api_assembly.out_of_sync;
- }
-
- return true; // Failed to load, assume they're outdated assemblies
-}
-
-String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync, const bool *p_editor_api_out_of_sync) {
-#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
- ( \
- (m_out_of_sync ? String("The assembly is invalidated ") : String("The assembly was not found ")) + \
- (m_prebuilt_exists ? String("and the prebuilt assemblies are missing.") : String("and we failed to copy the prebuilt assemblies.")))
-
- String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
-
- String core_assembly_path = dst_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String editor_assembly_path = dst_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
-
- bool api_assemblies_out_of_sync = false;
-
- if (p_core_api_out_of_sync && p_editor_api_out_of_sync) {
- api_assemblies_out_of_sync = *p_core_api_out_of_sync || *p_editor_api_out_of_sync;
- } else if (FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) {
- // Determine if they're out of sync
- if (!try_get_cached_api_hash_for(dst_assemblies_dir, api_assemblies_out_of_sync)) {
- api_assemblies_out_of_sync = _temp_domain_load_are_assemblies_out_of_sync(p_config);
- }
- }
-
- // Note: Even if only one of the assemblies if missing or out of sync, we update both
-
- if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) {
- return String(); // No update needed
- }
-
- print_verbose("Updating '" + p_config + "' API assemblies");
-
- String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
- String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
- String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
-
- if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path)) {
- return FAIL_REASON(api_assemblies_out_of_sync, /* prebuilt_exists: */ false);
- }
-
- // Copy the prebuilt Api
- if (!copy_prebuilt_api_assembly(ApiAssemblyInfo::API_CORE, p_config) ||
- !copy_prebuilt_api_assembly(ApiAssemblyInfo::API_EDITOR, p_config)) {
- return FAIL_REASON(api_assemblies_out_of_sync, /* prebuilt_exists: */ true);
- }
-
- // Cache the api hash of the assemblies we just copied
- create_cached_api_hash_for(dst_assemblies_dir);
-
- return String(); // Updated successfully
-
-#undef FAIL_REASON
+ return load_assembly("mscorlib", &corlib_assembly);
}
-#endif
-bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
- if (r_loaded_api_assembly.assembly) {
+bool GDMono::_load_core_api_assembly(GDMonoAssembly **r_loaded_api_assembly, const String &p_config) {
+ if (*r_loaded_api_assembly) {
return true;
}
-#ifdef TOOLS_ENABLED
- // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
-
- // If running the project manager, load it from the prebuilt API directory
- String assembly_dir = !Engine::get_singleton()->is_project_manager_hint()
- ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config)
- : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
-
- String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
-
- bool success = FileAccess::exists(assembly_path) &&
- load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly);
-#else
- bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &r_loaded_api_assembly.assembly, p_refonly);
-#endif
-
-#ifdef DEBUG_METHODS_ENABLED
- if (success) {
- ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_CORE);
- r_loaded_api_assembly.out_of_sync = get_api_core_hash() != api_assembly_ver.godot_api_hash;
- } else {
- r_loaded_api_assembly.out_of_sync = false;
- }
-#else
- r_loaded_api_assembly.out_of_sync = false;
-#endif
-
- return success;
+ return load_assembly(CORE_API_ASSEMBLY_NAME, r_loaded_api_assembly);
}
#ifdef TOOLS_ENABLED
-bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
- if (r_loaded_api_assembly.assembly) {
+bool GDMono::_load_editor_api_assembly(GDMonoAssembly **r_loaded_api_assembly, const String &p_config) {
+ if (*r_loaded_api_assembly) {
return true;
}
- // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
-
- // If running the project manager, load it from the prebuilt API directory
- String assembly_dir = !Engine::get_singleton()->is_project_manager_hint()
- ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config)
- : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
-
- String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
-
- bool success = FileAccess::exists(assembly_path) &&
- load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly);
-
-#ifdef DEBUG_METHODS_ENABLED
- if (success) {
- ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_EDITOR);
- r_loaded_api_assembly.out_of_sync = get_api_editor_hash() != api_assembly_ver.godot_api_hash;
- } else {
- r_loaded_api_assembly.out_of_sync = false;
- }
-#else
- r_loaded_api_assembly.out_of_sync = false;
-#endif
-
- return success;
+ return load_assembly(EDITOR_API_ASSEMBLY_NAME, r_loaded_api_assembly);
}
#endif
-bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly,
- const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) {
- if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) {
+bool GDMono::_try_load_api_assemblies() {
+ String config = get_expected_api_build_config();
+
+ if (!_load_core_api_assembly(&core_api_assembly, config)) {
if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load Core API assembly");
}
@@ -824,30 +574,15 @@ bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, Lo
}
#ifdef TOOLS_ENABLED
- if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) {
+ if (!_load_editor_api_assembly(&editor_api_assembly, config)) {
if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load Editor API assembly");
}
return false;
}
-
- if (r_editor_api_assembly.out_of_sync) {
- return false;
- }
#endif
- // Check if the core API assembly is out of sync only after trying to load the
- // editor API assembly. Otherwise, if both assemblies are out of sync, we would
- // only update the former as we won't know the latter also needs to be updated.
- if (r_core_api_assembly.out_of_sync) {
- return false;
- }
-
- if (p_callback) {
- return p_callback();
- }
-
- return true;
+ return _on_core_api_assembly_loaded();
}
bool GDMono::_on_core_api_assembly_loaded() {
@@ -862,72 +597,14 @@ bool GDMono::_on_core_api_assembly_loaded() {
return true;
}
-bool GDMono::_try_load_api_assemblies_preset() {
- return _try_load_api_assemblies(core_api_assembly, editor_api_assembly,
- get_expected_api_build_config(), /* refonly: */ false, _on_core_api_assembly_loaded);
-}
-
-void GDMono::_load_api_assemblies() {
- bool api_assemblies_loaded = _try_load_api_assemblies_preset();
-
-#if defined(TOOLS_ENABLED) && !defined(GD_MONO_SINGLE_APPDOMAIN)
- if (!api_assemblies_loaded) {
- // The API assemblies are out of sync or some other error happened. Fine, try one more time, but
- // this time update them from the prebuilt assemblies directory before trying to load them again.
-
- // Shouldn't happen. The project manager loads the prebuilt API assemblies
- CRASH_COND_MSG(Engine::get_singleton()->is_project_manager_hint(), "Failed to load one of the prebuilt API assemblies.");
-
- // 1. Unload the scripts domain
- Error domain_unload_err = _unload_scripts_domain();
- CRASH_COND_MSG(domain_unload_err != OK, "Mono: Failed to unload scripts domain.");
-
- // 2. Update the API assemblies
- String update_error = update_api_assemblies_from_prebuilt("Debug", &core_api_assembly.out_of_sync, &editor_api_assembly.out_of_sync);
- CRASH_COND_MSG(!update_error.is_empty(), update_error);
-
- // 3. Load the scripts domain again
- Error domain_load_err = _load_scripts_domain();
- CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain.");
-
- // 4. Try loading the updated assemblies
- api_assemblies_loaded = _try_load_api_assemblies_preset();
- }
-#endif
-
- if (!api_assemblies_loaded) {
- // welp... too bad
-
- if (_are_api_assemblies_out_of_sync()) {
- if (core_api_assembly.out_of_sync) {
- ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync.");
- } else if (!GDMonoCache::cached_data.godot_api_cache_updated) {
- ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed.");
- }
-
-#ifdef TOOLS_ENABLED
- if (editor_api_assembly.out_of_sync) {
- ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync.");
- }
-#endif
-
- CRASH_NOW();
- } else {
- CRASH_NOW_MSG("Failed to load one of the API assemblies.");
- }
- }
-}
-
#ifdef TOOLS_ENABLED
bool GDMono::_load_tools_assemblies() {
if (tools_assembly && tools_project_editor_assembly) {
return true;
}
- bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
- load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
-
- return success;
+ return load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
+ load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
}
#endif
@@ -946,7 +623,12 @@ bool GDMono::_load_project_assembly() {
if (success) {
mono_assembly_set_main(project_assembly->get_assembly());
- CSharpLanguage::get_singleton()->lookup_scripts_in_assembly(project_assembly);
+ MonoException *exc = nullptr;
+ GDMonoCache::cached_data.methodthunk_ScriptManagerBridge_LookupScriptsInAssembly.invoke(
+ mono_assembly_get_object(mono_domain_get(), project_assembly->get_assembly()), &exc);
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ }
}
return success;
@@ -955,11 +637,8 @@ bool GDMono::_load_project_assembly() {
void GDMono::_install_trace_listener() {
#ifdef DEBUG_ENABLED
// Install the trace listener now before the project assembly is loaded
- GDMonoClass *debug_utils = get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, "DebuggingUtils");
- GDMonoMethod *install_func = debug_utils->get_method("InstallTraceListener");
-
MonoException *exc = nullptr;
- install_func->invoke_raw(nullptr, nullptr, &exc);
+ GDMonoCache::cached_data.methodthunk_DebuggingUtils_InstallTraceListener.invoke(&exc);
if (exc) {
GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_PRINT("Failed to install 'System.Diagnostics.Trace' listener.");
@@ -1007,9 +686,9 @@ Error GDMono::_unload_scripts_domain() {
_domain_assemblies_cleanup(mono_domain_get_id(scripts_domain));
- core_api_assembly.assembly = nullptr;
+ core_api_assembly = nullptr;
#ifdef TOOLS_ENABLED
- editor_api_assembly.assembly = nullptr;
+ editor_api_assembly = nullptr;
#endif
project_assembly = nullptr;
@@ -1051,7 +730,9 @@ Error GDMono::reload_scripts_domain() {
// Load assemblies. The API and tools assemblies are required,
// the application is aborted if these assemblies cannot be loaded.
- _load_api_assemblies();
+ if (!_try_load_api_assemblies()) {
+ CRASH_NOW_MSG("Failed to load one of the API assemblies.");
+ }
#if defined(TOOLS_ENABLED)
bool tools_assemblies_loaded = _load_tools_assemblies();
@@ -1104,49 +785,6 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
}
#endif
-GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
- MonoImage *image = mono_class_get_image(p_raw_class);
-
- if (image == corlib_assembly->get_image()) {
- return corlib_assembly->get_class(p_raw_class);
- }
-
- int32_t domain_id = mono_domain_get_id(mono_domain_get());
- HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
-
- for (const KeyValue<String, GDMonoAssembly *> &E : domain_assemblies) {
- GDMonoAssembly *assembly = E.value;
- if (assembly->get_image() == image) {
- GDMonoClass *klass = assembly->get_class(p_raw_class);
- if (klass) {
- return klass;
- }
- }
- }
-
- return nullptr;
-}
-
-GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) {
- GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name);
- if (klass) {
- return klass;
- }
-
- int32_t domain_id = mono_domain_get_id(mono_domain_get());
- HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
-
- for (const KeyValue<String, GDMonoAssembly *> &E : domain_assemblies) {
- GDMonoAssembly *assembly = E.value;
- klass = assembly->get_class(p_namespace, p_name);
- if (klass) {
- return klass;
- }
- }
-
- return nullptr;
-}
-
void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];