diff options
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 1 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 103 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.h | 13 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 10 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 5 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.cpp | 13 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.h | 3 |
7 files changed, 77 insertions, 71 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 43a39a4966..560788fb3a 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -1006,6 +1006,7 @@ bool GDMono::_load_project_assembly() { if (success) { mono_assembly_set_main(project_assembly->get_assembly()); + CSharpLanguage::get_singleton()->lookup_scripts_in_assembly(project_assembly); } return success; diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 1fe06bfbee..a1556bace5 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -345,6 +345,45 @@ String GDMonoAssembly::get_path() const { return String::utf8(mono_image_get_filename(image)); } +bool GDMonoAssembly::has_attribute(GDMonoClass *p_attr_class) { +#ifdef DEBUG_ENABLED + ERR_FAIL_NULL_V(p_attr_class, false); +#endif + + if (!attrs_fetched) { + fetch_attributes(); + } + + if (!attributes) { + return false; + } + + return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); +} + +MonoObject *GDMonoAssembly::get_attribute(GDMonoClass *p_attr_class) { +#ifdef DEBUG_ENABLED + ERR_FAIL_NULL_V(p_attr_class, nullptr); +#endif + + if (!attrs_fetched) { + fetch_attributes(); + } + + if (!attributes) { + return nullptr; + } + + return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); +} + +void GDMonoAssembly::fetch_attributes() { + ERR_FAIL_COND(attributes != nullptr); + + attributes = mono_custom_attrs_from_assembly(assembly); + attrs_fetched = true; +} + GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const StringName &p_name) { ERR_FAIL_NULL_V(image, nullptr); @@ -390,70 +429,6 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) { return wrapped_class; } -GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) { - GDMonoClass *match = nullptr; - - if (gdobject_class_cache_updated) { - Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class); - - if (result) { - match = result->get(); - } - } else { - List<GDMonoClass *> nested_classes; - - int rows = mono_image_get_table_rows(image, MONO_TABLE_TYPEDEF); - - for (int i = 1; i < rows; i++) { - MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF); - - if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) { - continue; - } - - GDMonoClass *current = get_class(mono_class); - - if (!current) { - continue; - } - - nested_classes.push_back(current); - - if (!match && current->get_name() == p_class) { - match = current; - } - - while (!nested_classes.is_empty()) { - GDMonoClass *current_nested = nested_classes.front()->get(); - nested_classes.pop_front(); - - void *iter = nullptr; - - while (true) { - MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter); - - if (!raw_nested) { - break; - } - - GDMonoClass *nested_class = get_class(raw_nested); - - if (nested_class) { - gdobject_class_cache.insert(nested_class->get_name(), nested_class); - nested_classes.push_back(nested_class); - } - } - } - - gdobject_class_cache.insert(current->get_name(), current); - } - - gdobject_class_cache_updated = true; - } - - return match; -} - GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) { if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) { return GDMono::get_singleton()->get_corlib_assembly(); diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 350fcf3210..6191c491f4 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -71,13 +71,13 @@ class GDMonoAssembly { MonoImage *image; MonoAssembly *assembly; + bool attrs_fetched = false; + MonoCustomAttrInfo *attributes = nullptr; + #ifdef GD_MONO_HOT_RELOAD uint64_t modified_time = 0; #endif - bool gdobject_class_cache_updated = false; - Map<StringName, GDMonoClass *> gdobject_class_cache; - HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes; Map<MonoClass *, GDMonoClass *> cached_raw; @@ -111,11 +111,14 @@ public: String get_path() const; + bool has_attribute(GDMonoClass *p_attr_class); + MonoObject *get_attribute(GDMonoClass *p_attr_class); + + void fetch_attributes(); + GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name); GDMonoClass *get_class(MonoClass *p_mono_class); - GDMonoClass *get_object_derived_class(const StringName &p_class); - static String find_assembly(const String &p_name); static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String()); diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index aea467660f..d66cc29b9a 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -148,6 +148,11 @@ void CachedData::clear_godot_api_cache() { class_PuppetSyncAttribute = nullptr; class_GodotMethodAttribute = nullptr; field_GodotMethodAttribute_methodName = nullptr; + class_ScriptPathAttribute = nullptr; + field_ScriptPathAttribute_path = nullptr; + class_AssemblyHasScriptsAttribute = nullptr; + field_AssemblyHasScriptsAttribute_requiresLookup = nullptr; + field_AssemblyHasScriptsAttribute_scriptTypes = nullptr; field_GodotObject_ptr = nullptr; field_StringName_ptr = nullptr; @@ -272,6 +277,11 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute)); CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute)); CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); + CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute)); + CACHE_FIELD_AND_CHECK(ScriptPathAttribute, path, CACHED_CLASS(ScriptPathAttribute)->get_field("path")); + CACHE_CLASS_AND_CHECK(AssemblyHasScriptsAttribute, GODOT_API_CLASS(AssemblyHasScriptsAttribute)); + CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, requiresLookup, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("requiresLookup")); + CACHE_FIELD_AND_CHECK(AssemblyHasScriptsAttribute, scriptTypes, CACHED_CLASS(AssemblyHasScriptsAttribute)->get_field("scriptTypes")); CACHE_FIELD_AND_CHECK(GodotObject, ptr, CACHED_CLASS(GodotObject)->get_field(BINDINGS_PTR_FIELD)); CACHE_FIELD_AND_CHECK(StringName, ptr, CACHED_CLASS(StringName)->get_field(BINDINGS_PTR_FIELD)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index fb75cb4b1c..51370da452 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -119,6 +119,11 @@ struct CachedData { GDMonoClass *class_PuppetSyncAttribute; GDMonoClass *class_GodotMethodAttribute; GDMonoField *field_GodotMethodAttribute_methodName; + GDMonoClass *class_ScriptPathAttribute; + GDMonoField *field_ScriptPathAttribute_path; + GDMonoClass *class_AssemblyHasScriptsAttribute; + GDMonoField *field_AssemblyHasScriptsAttribute_requiresLookup; + GDMonoField *field_AssemblyHasScriptsAttribute_scriptTypes; GDMonoField *field_GodotObject_ptr; GDMonoField *field_StringName_ptr; diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 65e2680905..fa93c6533a 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -43,7 +43,6 @@ #include <mono/metadata/exception.h> namespace GDMonoInternals { - void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { // This method should not fail @@ -113,9 +112,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { void unhandled_exception(MonoException *p_exc) { mono_print_unhandled_exception((MonoObject *)p_exc); + gd_unhandled_exception_event(p_exc); if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) { // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders + mono_unhandled_exception((MonoObject *)p_exc); GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr); GD_UNREACHABLE(); } else { @@ -127,4 +128,14 @@ void unhandled_exception(MonoException *p_exc) { #endif } } + +void gd_unhandled_exception_event(MonoException *p_exc) { + MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image(); + + MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD"); + MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1); + void *args[1]; + args[0] = p_exc; + mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr); +} } // namespace GDMonoInternals diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 34d2d35b2d..26eb270eee 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -38,7 +38,6 @@ #include "core/object/class_db.h" namespace GDMonoInternals { - void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); /** @@ -46,6 +45,8 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); * Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead. */ void unhandled_exception(MonoException *p_exc); + +void gd_unhandled_exception_event(MonoException *p_exc); } // namespace GDMonoInternals #endif // GD_MONO_INTERNALS_H |