diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 12 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.h | 2 | ||||
-rw-r--r-- | modules/mono/editor/code_completion.cpp | 2 | ||||
-rw-r--r-- | modules/mono/editor/editor_internal_calls.cpp | 2 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs | 19 | ||||
-rw-r--r-- | modules/mono/glue/string_glue.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 54 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.h | 16 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 8 | ||||
-rw-r--r-- | modules/mono/register_types.cpp | 8 |
11 files changed, 90 insertions, 45 deletions
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 632f7d61cc..7fdef8ff45 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -3130,8 +3130,18 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::CALLABLE: + ERR_FAIL_COND_V_MSG(r_iarg.type.cname != name_cache.type_Callable, false, + "Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value of type '" + String(name_cache.type_Callable) + "'."); + ERR_FAIL_COND_V_MSG(!p_val.is_zero(), false, + "Parameter of type '" + String(r_iarg.type.cname) + "' can only have null/zero as the default value."); + r_iarg.default_argument = "default"; + break; case Variant::SIGNAL: - CRASH_NOW_MSG("Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value."); + ERR_FAIL_COND_V_MSG(r_iarg.type.cname != name_cache.type_Signal, false, + "Parameter of type '" + String(r_iarg.type.cname) + "' cannot have a default value of type '" + String(name_cache.type_Signal) + "'."); + ERR_FAIL_COND_V_MSG(!p_val.is_zero(), false, + "Parameter of type '" + String(r_iarg.type.cname) + "' can only have null/zero as the default value."); + r_iarg.default_argument = "default"; break; default: CRASH_NOW_MSG("Unexpected Variant type: " + itos(p_val.get_type())); diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index a649181b20..8a85a1acbd 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -536,6 +536,8 @@ class BindingsGenerator { StringName type_Object = StaticCString::create("Object"); StringName type_RefCounted = StaticCString::create("RefCounted"); StringName type_RID = StaticCString::create("RID"); + StringName type_Callable = StaticCString::create("Callable"); + StringName type_Signal = StaticCString::create("Signal"); StringName type_String = StaticCString::create("String"); StringName type_StringName = StaticCString::create("StringName"); StringName type_NodePath = StaticCString::create("NodePath"); diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index b7b36a92d8..d911f6461c 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -121,7 +121,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr case CompletionKind::NODE_PATHS: { { // AutoLoads - Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); + OrderedHashMap<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : autoloads) { const ProjectSettings::AutoloadInfo &info = E.value; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 8164f459ca..6692a6efec 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -241,7 +241,7 @@ MonoBoolean godot_icall_Internal_IsAssembliesReloadingNeeded() { void godot_icall_Internal_ReloadAssemblies(MonoBoolean p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD - _GodotSharp::get_singleton()->call_deferred(SNAME("_reload_assemblies"), (bool)p_soft_reload); + mono_bind::GodotSharp::get_singleton()->call_deferred(SNAME("_reload_assemblies"), (bool)p_soft_reload); #endif } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index d9665cbf2b..e619ad74e9 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -64,7 +64,7 @@ namespace Godot /// <summary> /// If the string is a path to a file, return the path to the file without the extension. /// </summary> - public static string BaseName(this string instance) + public static string GetBaseName(this string instance) { int index = instance.LastIndexOf('.'); @@ -339,7 +339,7 @@ namespace Godot /// <summary> /// If the string is a path to a file, return the extension. /// </summary> - public static string Extension(this string instance) + public static string GetExtension(this string instance) { int pos = instance.FindLast("."); @@ -575,7 +575,7 @@ namespace Godot /// <summary> /// If the string is a path to a file or directory, return <see langword="true"/> if the path is absolute. /// </summary> - public static bool IsAbsPath(this string instance) + public static bool IsAbsolutePath(this string instance) { if (string.IsNullOrEmpty(instance)) return false; @@ -590,7 +590,7 @@ namespace Godot /// </summary> public static bool IsRelPath(this string instance) { - return !IsAbsPath(instance); + return !IsAbsolutePath(instance); } /// <summary> @@ -1103,6 +1103,17 @@ namespace Godot } /// <summary> + /// Returns a simplified canonical path. + /// </summary> + public static string SimplifyPath(this string instance) + { + return godot_icall_String_simplify_path(instance); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + internal extern static string godot_icall_String_simplify_path(string str); + + /// <summary> /// Split the string by a divisor string, return an array of the substrings. /// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". /// </summary> diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp index 18a9221f89..bb80a836ad 100644 --- a/modules/mono/glue/string_glue.cpp +++ b/modules/mono/glue/string_glue.cpp @@ -67,6 +67,11 @@ MonoString *godot_icall_String_sha256_text(MonoString *p_str) { return GDMonoMarshal::mono_string_from_godot(ret); } +MonoString *godot_icall_String_simplify_path(MonoString *p_str) { + String ret = GDMonoMarshal::mono_string_to_godot(p_str).simplify_path(); + return GDMonoMarshal::mono_string_from_godot(ret); +} + void godot_register_string_icalls() { GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", godot_icall_String_md5_buffer); GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", godot_icall_String_md5_text); @@ -74,6 +79,7 @@ void godot_register_string_icalls() { GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", godot_icall_String_rfindn); GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", godot_icall_String_sha256_buffer); GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", godot_icall_String_sha256_text); + GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_simplify_path", godot_icall_String_simplify_path); } #endif // MONO_GLUE_ENABLED diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 299344bb93..1b1349a3a3 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -73,7 +73,7 @@ #endif // TODO: -// This has turn into a gigantic mess. There's too much going on here. Too much #ifdef as well. +// This has turned into a gigantic mess. There's too much going on here. Too much #ifdef as well. // It's just painful to read... It needs to be re-structured. Please, clean this up, future me. GDMono *GDMono::singleton = nullptr; @@ -1335,23 +1335,25 @@ GDMono::~GDMono() { singleton = nullptr; } -_GodotSharp *_GodotSharp::singleton = nullptr; +namespace mono_bind { -void _GodotSharp::attach_thread() { +GodotSharp *GodotSharp::singleton = nullptr; + +void GodotSharp::attach_thread() { GDMonoUtils::attach_current_thread(); } -void _GodotSharp::detach_thread() { +void GodotSharp::detach_thread() { GDMonoUtils::detach_current_thread(); } -int32_t _GodotSharp::get_domain_id() { +int32_t GodotSharp::get_domain_id() { MonoDomain *domain = mono_domain_get(); ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } -int32_t _GodotSharp::get_scripts_domain_id() { +int32_t GodotSharp::get_scripts_domain_id() { ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(), -1, "The Mono runtime is not initialized"); MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); @@ -1359,21 +1361,21 @@ int32_t _GodotSharp::get_scripts_domain_id() { return mono_domain_get_id(domain); } -bool _GodotSharp::is_scripts_domain_loaded() { +bool GodotSharp::is_scripts_domain_loaded() { return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr; } -bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { +bool GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(p_domain_id); } -bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { +bool GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); } -bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { +bool GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { GDMono *gd_mono = GDMono::get_singleton(); ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(), @@ -1388,15 +1390,15 @@ bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { return mono_domain_is_unloading(p_domain); } -bool _GodotSharp::is_runtime_shutting_down() { +bool GodotSharp::is_runtime_shutting_down() { return mono_runtime_is_shutting_down(); } -bool _GodotSharp::is_runtime_initialized() { +bool GodotSharp::is_runtime_initialized() { return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized(); } -void _GodotSharp::_reload_assemblies(bool p_soft_reload) { +void GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD CRASH_COND(CSharpLanguage::get_singleton() == nullptr); // This method may be called more than once with `call_deferred`, so we need to check @@ -1407,24 +1409,26 @@ void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #endif } -void _GodotSharp::_bind_methods() { - ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread); - ClassDB::bind_method(D_METHOD("detach_thread"), &_GodotSharp::detach_thread); +void GodotSharp::_bind_methods() { + ClassDB::bind_method(D_METHOD("attach_thread"), &GodotSharp::attach_thread); + ClassDB::bind_method(D_METHOD("detach_thread"), &GodotSharp::detach_thread); - ClassDB::bind_method(D_METHOD("get_domain_id"), &_GodotSharp::get_domain_id); - ClassDB::bind_method(D_METHOD("get_scripts_domain_id"), &_GodotSharp::get_scripts_domain_id); - ClassDB::bind_method(D_METHOD("is_scripts_domain_loaded"), &_GodotSharp::is_scripts_domain_loaded); - ClassDB::bind_method(D_METHOD("is_domain_finalizing_for_unload", "domain_id"), &_GodotSharp::_is_domain_finalizing_for_unload); + ClassDB::bind_method(D_METHOD("get_domain_id"), &GodotSharp::get_domain_id); + ClassDB::bind_method(D_METHOD("get_scripts_domain_id"), &GodotSharp::get_scripts_domain_id); + ClassDB::bind_method(D_METHOD("is_scripts_domain_loaded"), &GodotSharp::is_scripts_domain_loaded); + ClassDB::bind_method(D_METHOD("is_domain_finalizing_for_unload", "domain_id"), &GodotSharp::_is_domain_finalizing_for_unload); - ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &_GodotSharp::is_runtime_shutting_down); - ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &_GodotSharp::is_runtime_initialized); - ClassDB::bind_method(D_METHOD("_reload_assemblies"), &_GodotSharp::_reload_assemblies); + ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &GodotSharp::is_runtime_shutting_down); + ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &GodotSharp::is_runtime_initialized); + ClassDB::bind_method(D_METHOD("_reload_assemblies"), &GodotSharp::_reload_assemblies); } -_GodotSharp::_GodotSharp() { +GodotSharp::GodotSharp() { singleton = this; } -_GodotSharp::~_GodotSharp() { +GodotSharp::~GodotSharp() { singleton = nullptr; } + +} // namespace mono_bind diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 5accc21f8e..4170e5053f 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -293,8 +293,10 @@ public: gdmono::ScopeExitDomainUnload __gdmono__scope__exit__domain__unload__(m_mono_domain); \ (void)__gdmono__scope__exit__domain__unload__; -class _GodotSharp : public Object { - GDCLASS(_GodotSharp, Object); +namespace mono_bind { + +class GodotSharp : public Object { + GDCLASS(GodotSharp, Object); friend class GDMono; @@ -303,11 +305,11 @@ class _GodotSharp : public Object { void _reload_assemblies(bool p_soft_reload); protected: - static _GodotSharp *singleton; + static GodotSharp *singleton; static void _bind_methods(); public: - static _GodotSharp *get_singleton() { return singleton; } + static GodotSharp *get_singleton() { return singleton; } void attach_thread(); void detach_thread(); @@ -323,8 +325,10 @@ public: bool is_runtime_shutting_down(); bool is_runtime_initialized(); - _GodotSharp(); - ~_GodotSharp(); + GodotSharp(); + ~GodotSharp(); }; +} // namespace mono_bind + #endif // GD_MONO_H diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 60047545c4..cf76c23926 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -91,7 +91,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { // The object was just created, no script instance binding should have been attached CRASH_COND(CSharpLanguage::has_instance_binding(unmanaged)); - void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding); + void *data; + { + MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex()); + data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding); + } // Should be thread safe because the object was just created and nothing else should be referencing it CSharpLanguage::set_instance_binding(unmanaged, data); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 9f2977bfa2..c9789bf270 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -1686,7 +1686,9 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) { Object *target = p_managed_callable.target ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : nullptr; - StringName *method_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)); + StringName *method_ptr = p_managed_callable.method_string_name ? + unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)) : + nullptr; StringName method = method_ptr ? *method_ptr : StringName(); return Callable(target, method); } @@ -1732,7 +1734,9 @@ Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) { Object *owner = p_managed_signal.owner ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : nullptr; - StringName *name_ptr = unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)); + StringName *name_ptr = p_managed_signal.name_string_name ? + unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)) : + nullptr; StringName name = name_ptr ? *name_ptr : StringName(); return Signal(owner, name); } diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 2ba89eac55..98e83335e9 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -38,15 +38,15 @@ CSharpLanguage *script_language_cs = nullptr; Ref<ResourceFormatLoaderCSharpScript> resource_loader_cs; Ref<ResourceFormatSaverCSharpScript> resource_saver_cs; -_GodotSharp *_godotsharp = nullptr; +mono_bind::GodotSharp *_godotsharp = nullptr; void register_mono_types() { GDREGISTER_CLASS(CSharpScript); - _godotsharp = memnew(_GodotSharp); + _godotsharp = memnew(mono_bind::GodotSharp); - GDREGISTER_CLASS(_GodotSharp); - Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", _GodotSharp::get_singleton())); + GDREGISTER_CLASS(mono_bind::GodotSharp); + Engine::get_singleton()->add_singleton(Engine::Singleton("GodotSharp", mono_bind::GodotSharp::get_singleton())); script_language_cs = memnew(CSharpLanguage); script_language_cs->set_language_index(ScriptServer::get_language_count()); |