Error GDMono::reload_scripts_domain() { ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG); if (scripts_domain) { Error err = _unload_scripts_domain(); if (err != OK) { ERR_PRINT("Mono: Failed to unload scripts domain"); return err; } } Error err = _load_scripts_domain(); if (err != OK) { ERR_PRINT("Mono: Failed to load scripts domain"); return err; } #ifdef MONO_GLUE_ENABLED if (!_load_api_assemblies()) { return ERR_CANT_OPEN; } if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { // Everything is fine with the api assemblies, load the project assembly _load_project_assembly(); } else { // The assembly was successfully loaded, but the full api could not be cached. // This is most likely an outdated assembly loaded because of an invalid version in the metadata, // so we invalidate the version in the metadata and unload the script domain. if (core_api_assembly_out_of_sync) { ERR_PRINT("The loaded Core API assembly is out of sync"); metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed"); metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); } if (editor_api_assembly_out_of_sync) { ERR_PRINT("The loaded Editor API assembly is out of sync"); metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); } Error err = _unload_scripts_domain(); if (err != OK) { WARN_PRINT("Mono: Failed to unload scripts domain"); } return ERR_CANT_RESOLVE; } if (!_load_project_assembly()) return ERR_CANT_OPEN; #else print_verbose("Mono: Glue disabled, ignoring script assemblies."); #endif return OK; }
Error GDMono::reload_scripts_domain() { ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG); if (scripts_domain) { Error err = _unload_scripts_domain(); if (err != OK) { ERR_PRINT("Mono: Failed to unload scripts domain"); return err; } } Error err = _load_scripts_domain(); if (err != OK) { ERR_PRINT("Mono: Failed to load scripts domain"); return err; } if (!_load_all_script_assemblies()) { if (OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->printerr("Mono: Failed to load script assemblies\n"); return ERR_CANT_OPEN; } return OK; }
void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); print_verbose("Mono: Initializing module..."); #ifdef DEBUG_METHODS_ENABLED _initialize_and_check_api_hashes(); #endif GDMonoLog::get_singleton()->initialize(); #ifdef MONO_PRINT_HANDLER_ENABLED mono_trace_set_print_handler(gdmono_MonoPrintCallback); mono_trace_set_printerr_handler(gdmono_MonoPrintCallback); #endif #ifdef WINDOWS_ENABLED mono_reg_info = MonoRegUtils::find_mono(); CharString assembly_dir; CharString config_dir; if (mono_reg_info.assembly_dir.length() && DirAccess::exists(mono_reg_info.assembly_dir)) { assembly_dir = mono_reg_info.assembly_dir.utf8(); } if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) { config_dir = mono_reg_info.config_dir.utf8(); } mono_set_dirs(assembly_dir.length() ? assembly_dir.get_data() : NULL, config_dir.length() ? config_dir.get_data() : NULL); #elif OSX_ENABLED mono_set_dirs(NULL, NULL); { const char *assembly_rootdir = mono_assembly_getrootdir(); const char *config_dir = mono_get_config_dir(); if (!assembly_rootdir || !config_dir || !DirAccess::exists(assembly_rootdir) || !DirAccess::exists(config_dir)) { Vector<const char *> locations; locations.push_back("/Library/Frameworks/Mono.framework/Versions/Current/"); locations.push_back("/usr/local/var/homebrew/linked/mono/"); for (int i = 0; i < locations.size(); i++) { String hint_assembly_rootdir = path_join(locations[i], "lib"); String hint_mscorlib_path = path_join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll"); String hint_config_dir = path_join(locations[i], "etc"); if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) { mono_set_dirs(hint_assembly_rootdir.utf8().get_data(), hint_config_dir.utf8().get_data()); break; } } } } #else mono_set_dirs(NULL, NULL); #endif GDMonoAssembly::initialize(); #ifdef DEBUG_ENABLED gdmono_debug_init(); #endif mono_config_parse(NULL); mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL); root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319"); ERR_EXPLAIN("Mono: Failed to initialize runtime"); ERR_FAIL_NULL(root_domain); GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread()); setup_runtime_main_args(); // Required for System.Environment.GetCommandLineArgs runtime_initialized = true; print_verbose("Mono: Runtime initialized"); // mscorlib assembly MUST be present at initialization ERR_EXPLAIN("Mono: Failed to load mscorlib assembly"); ERR_FAIL_COND(!_load_corlib_assembly()); #ifdef TOOLS_ENABLED // The tools domain must be loaded here, before the scripts domain. // Otherwise domain unload on the scripts domain will hang indefinitely. ERR_EXPLAIN("Mono: Failed to load tools domain"); ERR_FAIL_COND(_load_tools_domain() != OK); // TODO move to editor init callback, and do it lazily when required before editor init (e.g.: bindings generation) ERR_EXPLAIN("Mono: Failed to load Editor Tools assembly"); ERR_FAIL_COND(!_load_editor_tools_assembly()); #endif ERR_EXPLAIN("Mono: Failed to load scripts domain"); ERR_FAIL_COND(_load_scripts_domain() != OK); #ifdef DEBUG_ENABLED bool debugger_attached = _wait_for_debugger_msecs(500); if (!debugger_attached && OS::get_singleton()->is_stdout_verbose()) print_error("Mono: Debugger wait timeout"); #endif _register_internal_calls(); // The following assemblies are not required at initialization #ifdef MONO_GLUE_ENABLED if (_load_api_assemblies()) { if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { // Everything is fine with the api assemblies, load the project assembly _load_project_assembly(); } else { #ifdef TOOLS_ENABLED // The assembly was successfully loaded, but the full api could not be cached. // This is most likely an outdated assembly loaded because of an invalid version in the metadata, // so we invalidate the version in the metadata and unload the script domain. if (core_api_assembly_out_of_sync) { ERR_PRINT("The loaded Core API assembly is out of sync"); metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed"); metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); } if (editor_api_assembly_out_of_sync) { ERR_PRINT("The loaded Editor API assembly is out of sync"); metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); } print_line("Mono: Proceeding to unload scripts domain because of invalid API assemblies."); Error err = _unload_scripts_domain(); if (err != OK) { WARN_PRINT("Mono: Failed to unload scripts domain"); } #else ERR_PRINT("The loaded API assembly is invalid"); CRASH_NOW(); #endif } } #else print_verbose("Mono: Glue disabled, ignoring script assemblies."); #endif print_verbose("Mono: INITIALIZED"); }
void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); OS::get_singleton()->print("Mono: Initializing module...\n"); #ifdef DEBUG_METHODS_ENABLED _initialize_and_check_api_hashes(); #endif GDMonoLog::get_singleton()->initialize(); #ifdef MONO_PRINT_HANDLER_ENABLED mono_trace_set_print_handler(gdmono_MonoPrintCallback); mono_trace_set_printerr_handler(gdmono_MonoPrintCallback); #endif #ifdef WINDOWS_ENABLED mono_reg_info = MonoRegUtils::find_mono(); CharString assembly_dir; CharString config_dir; if (mono_reg_info.assembly_dir.length() && DirAccess::exists(mono_reg_info.assembly_dir)) { assembly_dir = mono_reg_info.assembly_dir.utf8(); } if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) { config_dir = mono_reg_info.config_dir.utf8(); } mono_set_dirs(assembly_dir.length() ? assembly_dir.get_data() : NULL, config_dir.length() ? config_dir.get_data() : NULL); #else mono_set_dirs(NULL, NULL); #endif GDMonoAssembly::initialize(); #ifdef DEBUG_ENABLED gdmono_debug_init(); #endif mono_config_parse(NULL); root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319"); ERR_EXPLAIN("Mono: Failed to initialize runtime"); ERR_FAIL_NULL(root_domain); GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread()); runtime_initialized = true; OS::get_singleton()->print("Mono: Runtime initialized\n"); // mscorlib assembly MUST be present at initialization ERR_EXPLAIN("Mono: Failed to load mscorlib assembly"); ERR_FAIL_COND(!_load_corlib_assembly()); #ifdef TOOLS_ENABLED // The tools domain must be loaded here, before the scripts domain. // Otherwise domain unload on the scripts domain will hang indefinitely. ERR_EXPLAIN("Mono: Failed to load tools domain"); ERR_FAIL_COND(_load_tools_domain() != OK); // TODO move to editor init callback, and do it lazily when required before editor init (e.g.: bindings generation) ERR_EXPLAIN("Mono: Failed to load Editor Tools assembly"); ERR_FAIL_COND(!_load_editor_tools_assembly()); #endif ERR_EXPLAIN("Mono: Failed to load scripts domain"); ERR_FAIL_COND(_load_scripts_domain() != OK); #ifdef DEBUG_ENABLED bool debugger_attached = _wait_for_debugger_msecs(500); if (!debugger_attached && OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->printerr("Mono: Debugger wait timeout\n"); #endif _register_internal_calls(); // The following assemblies are not required at initialization _load_all_script_assemblies(); mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL); OS::get_singleton()->print("Mono: INITIALIZED\n"); }