diff --git a/core/os/os.h b/core/os/os.h index a08bdcb6089..20a3494e115 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -266,6 +266,7 @@ public: virtual bool has_environment(const String &p_var) const = 0; virtual String get_environment(const String &p_var) const = 0; + virtual bool set_environment(const String &p_var, const String &p_value) const = 0; virtual String get_name() = 0; virtual List get_cmdline_args() const { return _cmdline; } diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index ce1c1832429..39a8fbc153c 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -469,6 +469,11 @@ String OS_Unix::get_environment(const String &p_var) const { return ""; } +bool OS_Unix::set_environment(const String &p_var, const String &p_value) const { + + return setenv(p_var.utf8().get_data(), p_var.utf8().get_data(), /* overwrite: */ true) == 0; +} + int OS_Unix::get_processor_count() const { return sysconf(_SC_NPROCESSORS_CONF); diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 2a23da6f289..09ab4aa1d81 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -95,6 +95,7 @@ public: virtual bool has_environment(const String &p_var) const; virtual String get_environment(const String &p_var) const; + virtual bool set_environment(const String &p_var, const String &p_value) const; virtual String get_locale() const; virtual int get_processor_count() const; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 0b21ba3347b..cb0ddf684e5 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -578,7 +578,7 @@ void CSharpLanguage::frame() { if (exc) { GDMonoUtils::debug_unhandled_exception(exc); - _UNREACHABLE_(); + GD_UNREACHABLE(); } } } @@ -1608,7 +1608,7 @@ bool CSharpInstance::refcount_decremented() { return ref_dying; } -MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(GDMonoClassMember *p_member) const { +MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(IMonoClassMember *p_member) const { if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) return MultiplayerAPI::RPC_MODE_REMOTE; @@ -2019,7 +2019,7 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve * Returns false if there was an error, otherwise true. * If there was an error, r_prop_info and r_exported are not assigned any value. */ -bool CSharpScript::_get_member_export(GDMonoClass *p_class, GDMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported) { +bool CSharpScript::_get_member_export(GDMonoClass *p_class, IMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported) { StringName name = p_member->get_name(); @@ -2034,9 +2034,9 @@ bool CSharpScript::_get_member_export(GDMonoClass *p_class, GDMonoClassMember *p ManagedType type; - if (p_member->get_member_type() == GDMonoClassMember::MEMBER_TYPE_FIELD) { + if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_FIELD) { type = static_cast(p_member)->get_type(); - } else if (p_member->get_member_type() == GDMonoClassMember::MEMBER_TYPE_PROPERTY) { + } else if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) { type = static_cast(p_member)->get_type(); } else { CRASH_NOW(); @@ -2050,7 +2050,7 @@ bool CSharpScript::_get_member_export(GDMonoClass *p_class, GDMonoClassMember *p return true; } - if (p_member->get_member_type() == GDMonoClassMember::MEMBER_TYPE_PROPERTY) { + if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) { GDMonoProperty *property = static_cast(p_member); if (!property->has_getter() || !property->has_setter()) { ERR_PRINTS("Cannot export property because it does not provide a getter or a setter: " + p_class->get_full_name() + "." + name.operator String()); diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 8a09be79a60..26fa7586368 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -127,7 +127,7 @@ class CSharpScript : public Script { bool _update_exports(); #ifdef TOOLS_ENABLED - bool _get_member_export(GDMonoClass *p_class, GDMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported); + bool _get_member_export(GDMonoClass *p_class, IMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported); #endif CSharpInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error); @@ -216,7 +216,7 @@ class CSharpInstance : public ScriptInstance { void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount); - MultiplayerAPI::RPCMode _member_get_rpc_mode(GDMonoClassMember *p_member) const; + MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const; public: MonoObject *get_mono_object() const; diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 5d9f4d8d54c..a040e4a344f 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -517,7 +517,7 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { // Remove old issues file - String issues_file = "msbuild_issues.csv"; + String issues_file = get_msbuild_issues_filename(); DirAccessRef d = DirAccess::create_for_path(log_dirpath); if (d->file_exists(issues_file)) { Error err = d->remove(issues_file); @@ -584,7 +584,8 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { exit_code = klass->get_field("exitCode")->get_int_value(mono_object); if (exit_code != 0) { - print_verbose("MSBuild finished with exit code " + itos(exit_code)); + String log_filepath = build_info.get_log_dirpath().plus_file(get_msbuild_log_filename()); + print_verbose("MSBuild exited with code: " + itos(exit_code) + ". Log file: " + log_filepath); } build_tab->on_build_exit(exit_code == 0 ? MonoBuildTab::RESULT_SUCCESS : MonoBuildTab::RESULT_ERROR); diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h index 2d535839165..652d30538a1 100644 --- a/modules/mono/editor/godotsharp_builds.h +++ b/modules/mono/editor/godotsharp_builds.h @@ -76,6 +76,9 @@ public: static void show_build_error_dialog(const String &p_message); + static const char *get_msbuild_issues_filename() { return "msbuild_issues.csv"; } + static const char *get_msbuild_log_filename() { return "msbuild_log.txt"; } + void build_exit_callback(const MonoBuildInfo &p_build_info, int p_exit_code); void restart_build(MonoBuildTab *p_build_tab); diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index cee4405826e..474ec8a458d 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -452,7 +452,7 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { EditorSettings *ed_settings = EditorSettings::get_singleton(); EDITOR_DEF("mono/editor/external_editor", EDITOR_NONE); - String settings_hint_str = "None"; + String settings_hint_str = "Disabled"; #ifdef WINDOWS_ENABLED settings_hint_str += ",MonoDevelop,Visual Studio Code"; diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index 55a334bc4e4..d3efa288e9b 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -187,7 +187,7 @@ void MonoBottomPanel::_view_log_pressed() { String log_dirpath = build_tab->get_build_info().get_log_dirpath(); - OS::get_singleton()->shell_open(log_dirpath.plus_file("msbuild_log.txt")); + OS::get_singleton()->shell_open(log_dirpath.plus_file(GodotSharpBuilds::get_msbuild_log_filename())); } } @@ -421,7 +421,7 @@ void MonoBuildTab::on_build_exit(BuildResult result) { build_exited = true; build_result = result; - _load_issues_from_file(logs_dir.plus_file("msbuild_issues.csv")); + _load_issues_from_file(logs_dir.plus_file(GodotSharpBuilds::get_msbuild_issues_filename())); _update_issues_list(); MonoBottomPanel::get_singleton()->raise_build_tab(this); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 900caefe1ca..5ad383e99d6 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -54,17 +54,6 @@ #include "main/main.h" #endif -#ifdef MONO_PRINT_HANDLER_ENABLED -void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) { - - if (is_stdout) { - OS::get_singleton()->print(string); - } else { - OS::get_singleton()->printerr(string); - } -} -#endif - GDMono *GDMono::singleton = NULL; namespace { @@ -150,6 +139,40 @@ void gdmono_debug_init() { } // namespace +void GDMono::add_mono_shared_libs_dir_to_path() { + // By default Mono seems to search shared libraries in the following directories: + // Current working directory, @executable_path@ and PATH + // The parent directory of the image file (assembly where the dllimport method is declared) + // @executable_path@/../lib + // @executable_path@/../Libraries (__MACH__ only) + + // This does not work when embedding Mono unless we use the same directory structure. + // To fix this we append the directory containing our shared libraries to PATH. + +#if defined(WINDOWS_ENABLED) || defined(UNIX_ENABLED) + String path_var("PATH"); + String path_value = OS::get_singleton()->get_environment(path_var); + +#ifdef WINDOWS_ENABLED + path_value += ';'; + + String bundled_bin_dir = GodotSharpDirs::get_data_mono_bin_dir(); + path_value += DirAccess::exists(bundled_bin_dir) ? bundled_bin_dir : mono_reg_info.bin_dir; +#else + path_value += ':'; + + String bundled_lib_dir = GodotSharpDirs::get_data_mono_lib_dir(); + if (DirAccess::exists(bundled_lib_dir)) { + path_value += bundled_lib_dir; + } else { + // TODO: Do we need to add the lib dir when using the system installed Mono on Unix platforms? + } +#endif + + OS::get_singleton()->set_environment(path_var, path_value); +#endif +} + void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); @@ -162,11 +185,6 @@ void GDMono::initialize() { GDMonoLog::get_singleton()->initialize(); -#ifdef MONO_PRINT_HANDLER_ENABLED - mono_trace_set_print_handler(gdmono_MonoPrintCallback); - mono_trace_set_printerr_handler(gdmono_MonoPrintCallback); -#endif - String assembly_rootdir; String config_dir; @@ -223,6 +241,8 @@ void GDMono::initialize() { mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL, config_dir.length() ? config_dir.utf8().get_data() : NULL); + add_mono_shared_libs_dir_to_path(); + GDMonoAssembly::initialize(); #ifdef DEBUG_ENABLED @@ -327,7 +347,7 @@ namespace GodotSharpBindings { uint64_t get_core_api_hash(); #ifdef TOOLS_ENABLED uint64_t get_editor_api_hash(); -#endif // TOOLS_ENABLED +#endif uint32_t get_bindings_version(); void register_generated_icalls(); @@ -344,29 +364,20 @@ void GDMono::_register_internal_calls() { #endif } -#ifdef DEBUG_METHODS_ENABLED void GDMono::_initialize_and_check_api_hashes() { - api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE); - #ifdef MONO_GLUE_ENABLED - if (api_core_hash != GodotSharpBindings::get_core_api_hash()) { + if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) { ERR_PRINT("Mono: Core API hash mismatch!"); } -#endif #ifdef TOOLS_ENABLED - api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); - -#ifdef MONO_GLUE_ENABLED - if (api_editor_hash != GodotSharpBindings::get_editor_api_hash()) { + if (get_api_editor_hash() != GodotSharpBindings::get_editor_api_hash()) { ERR_PRINT("Mono: Editor API hash mismatch!"); } -#endif - #endif // TOOLS_ENABLED +#endif // MONO_GLUE_ENABLED } -#endif // DEBUG_METHODS_ENABLED void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { @@ -915,7 +926,7 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) { ScriptDebugger::get_singleton()->idle_poll(); #endif abort(); - _UNREACHABLE_(); + GD_UNREACHABLE(); } GDMono::GDMono() { @@ -946,12 +957,10 @@ GDMono::GDMono() { editor_tools_assembly = NULL; #endif -#ifdef DEBUG_METHODS_ENABLED api_core_hash = 0; #ifdef TOOLS_ENABLED api_editor_hash = 0; #endif -#endif } GDMono::~GDMono() { @@ -1074,17 +1083,9 @@ void _GodotSharp::_bind_methods() { _GodotSharp::_GodotSharp() { singleton = this; - queue_empty = true; -#ifndef NO_THREADS - queue_mutex = Mutex::create(); -#endif } _GodotSharp::~_GodotSharp() { singleton = NULL; - - if (queue_mutex) { - memdelete(queue_mutex); - } } diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 13de3061b38..785b65ce130 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -134,13 +134,11 @@ class GDMono { Error _load_tools_domain(); #endif -#ifdef DEBUG_METHODS_ENABLED uint64_t api_core_hash; #ifdef TOOLS_ENABLED uint64_t api_editor_hash; #endif void _initialize_and_check_api_hashes(); -#endif GDMonoLog *gdmono_log; @@ -148,15 +146,23 @@ class GDMono { MonoRegInfo mono_reg_info; #endif + void add_mono_shared_libs_dir_to_path(); + protected: static GDMono *singleton; public: -#ifdef DEBUG_METHODS_ENABLED - uint64_t get_api_core_hash() { return api_core_hash; } + uint64_t get_api_core_hash() { + if (api_core_hash == 0) + api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE); + return api_core_hash; + } #ifdef TOOLS_ENABLED - uint64_t get_api_editor_hash() { return api_editor_hash; } -#endif + uint64_t get_api_editor_hash() { + if (api_editor_hash == 0) + api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); + return api_editor_hash; + } #endif #ifdef TOOLS_ENABLED @@ -268,12 +274,6 @@ class _GodotSharp : public Object { List np_delete_queue; List rid_delete_queue; - bool queue_empty; - -#ifndef NO_THREADS - Mutex *queue_mutex; -#endif - protected: static _GodotSharp *singleton; static void _bind_methods(); diff --git a/modules/mono/mono_gd/gd_mono_class_member.h b/modules/mono/mono_gd/gd_mono_class_member.h index 5bd21178ba2..3058b18c059 100644 --- a/modules/mono/mono_gd/gd_mono_class_member.h +++ b/modules/mono/mono_gd/gd_mono_class_member.h @@ -35,7 +35,7 @@ #include -class GDMonoClassMember { +class IMonoClassMember { public: enum Visibility { PRIVATE, @@ -51,7 +51,7 @@ public: MEMBER_TYPE_METHOD }; - virtual ~GDMonoClassMember() {} + virtual ~IMonoClassMember() {} virtual MemberType get_member_type() = 0; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index a9d993412ee..48fa3804568 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -505,20 +505,20 @@ bool GDMonoField::is_static() { return mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_STATIC; } -GDMonoClassMember::Visibility GDMonoField::get_visibility() { +IMonoClassMember::Visibility GDMonoField::get_visibility() { switch (mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_FIELD_ACCESS_MASK) { case MONO_FIELD_ATTR_PRIVATE: - return GDMonoClassMember::PRIVATE; + return IMonoClassMember::PRIVATE; case MONO_FIELD_ATTR_FAM_AND_ASSEM: - return GDMonoClassMember::PROTECTED_AND_INTERNAL; + return IMonoClassMember::PROTECTED_AND_INTERNAL; case MONO_FIELD_ATTR_ASSEMBLY: - return GDMonoClassMember::INTERNAL; + return IMonoClassMember::INTERNAL; case MONO_FIELD_ATTR_FAMILY: - return GDMonoClassMember::PROTECTED; + return IMonoClassMember::PROTECTED; case MONO_FIELD_ATTR_PUBLIC: - return GDMonoClassMember::PUBLIC; + return IMonoClassMember::PUBLIC; default: - ERR_FAIL_V(GDMonoClassMember::PRIVATE); + ERR_FAIL_V(IMonoClassMember::PRIVATE); } } diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h index 319e895ab9f..a3244101d8f 100644 --- a/modules/mono/mono_gd/gd_mono_field.h +++ b/modules/mono/mono_gd/gd_mono_field.h @@ -35,7 +35,7 @@ #include "gd_mono_class_member.h" #include "gd_mono_header.h" -class GDMonoField : public GDMonoClassMember { +class GDMonoField : public IMonoClassMember { GDMonoClass *owner; MonoClassField *mono_field; @@ -47,15 +47,15 @@ class GDMonoField : public GDMonoClassMember { MonoCustomAttrInfo *attributes; public: - virtual MemberType get_member_type() { return MEMBER_TYPE_FIELD; } + virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_FIELD; } - virtual StringName get_name() { return name; } + virtual StringName get_name() GD_FINAL { return name; } - virtual bool is_static(); - virtual Visibility get_visibility(); + virtual bool is_static() GD_FINAL; + virtual Visibility get_visibility() GD_FINAL; - virtual bool has_attribute(GDMonoClass *p_attr_class); - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class); + virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; void fetch_attributes(); _FORCE_INLINE_ ManagedType get_type() const { return type; } diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h index 23306d11b92..dd8c047386c 100644 --- a/modules/mono/mono_gd/gd_mono_header.h +++ b/modules/mono/mono_gd/gd_mono_header.h @@ -35,7 +35,7 @@ class GDMonoAssembly; class GDMonoClass; -class GDMonoClassMember; +class IMonoClassMember; class GDMonoField; class GDMonoProperty; class GDMonoMethod; diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 0574b0025df..0daa394e63e 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -72,7 +72,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { void unhandled_exception(MonoException *p_exc) { mono_unhandled_exception((MonoObject *)p_exc); // prints the exception as well abort(); - _UNREACHABLE_(); + GD_UNREACHABLE(); } } // namespace GDMonoInternals diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 09cb59ee6bc..2d77bde27c3 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -45,7 +45,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); * Do not call this function directly. * Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead. */ -_NO_RETURN_ void unhandled_exception(MonoException *p_exc); +GD_NORETURN void unhandled_exception(MonoException *p_exc); } // namespace GDMonoInternals diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index fa4850ca8c6..ec89df1959c 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -52,7 +52,7 @@ static int log_level_get_id(const char *p_log_level) { return -1; } -void gdmono_MonoLogCallback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { +static void mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { FileAccess *f = GDMonoLog::get_singleton()->get_log_file(); @@ -153,7 +153,7 @@ void GDMonoLog::initialize() { if (log_file) { print_verbose("Mono: Logfile is " + log_file_path); - mono_trace_set_log_handler(gdmono_MonoLogCallback, this); + mono_trace_set_log_handler(mono_log_callback, this); } else { OS::get_singleton()->printerr("Mono: No log file, using default log handler\n"); } diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 5e2deea43c2..4f86e02f87f 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -206,9 +206,10 @@ enum { // In the future we may force this if we want to ref return these structs #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY -// Sometimes clang-format can be an ass -GD_STATIC_ASSERT(MATCHES_Vector2 &&MATCHES_Rect2 &&MATCHES_Transform2D &&MATCHES_Vector3 && - MATCHES_Basis &&MATCHES_Quat &&MATCHES_Transform &&MATCHES_AABB &&MATCHES_Color &&MATCHES_Plane); +/* clang-format off */ +GD_STATIC_ASSERT(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && + MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color &&MATCHES_Plane); +/* clang-format on */ #endif } // namespace InteropLayout diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 071d852ce7b..7f11e4671d5 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -78,20 +78,20 @@ bool GDMonoMethod::is_static() { return mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_STATIC; } -GDMonoClassMember::Visibility GDMonoMethod::get_visibility() { +IMonoClassMember::Visibility GDMonoMethod::get_visibility() { switch (mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) { case MONO_METHOD_ATTR_PRIVATE: - return GDMonoClassMember::PRIVATE; + return IMonoClassMember::PRIVATE; case MONO_METHOD_ATTR_FAM_AND_ASSEM: - return GDMonoClassMember::PROTECTED_AND_INTERNAL; + return IMonoClassMember::PROTECTED_AND_INTERNAL; case MONO_METHOD_ATTR_ASSEM: - return GDMonoClassMember::INTERNAL; + return IMonoClassMember::INTERNAL; case MONO_METHOD_ATTR_FAMILY: - return GDMonoClassMember::PROTECTED; + return IMonoClassMember::PROTECTED; case MONO_METHOD_ATTR_PUBLIC: - return GDMonoClassMember::PUBLIC; + return IMonoClassMember::PUBLIC; default: - ERR_FAIL_V(GDMonoClassMember::PRIVATE); + ERR_FAIL_V(IMonoClassMember::PRIVATE); } } diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h index c4a994177ee..fc035d387c1 100644 --- a/modules/mono/mono_gd/gd_mono_method.h +++ b/modules/mono/mono_gd/gd_mono_method.h @@ -35,7 +35,7 @@ #include "gd_mono_class_member.h" #include "gd_mono_header.h" -class GDMonoMethod : public GDMonoClassMember { +class GDMonoMethod : public IMonoClassMember { StringName name; @@ -57,17 +57,17 @@ class GDMonoMethod : public GDMonoClassMember { MonoMethod *mono_method; public: - virtual MemberType get_member_type() { return MEMBER_TYPE_METHOD; } + virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_METHOD; } - virtual StringName get_name() { return name; } + virtual StringName get_name() GD_FINAL { return name; } - virtual bool is_static(); + virtual bool is_static() GD_FINAL; - virtual Visibility get_visibility(); + virtual Visibility get_visibility() GD_FINAL; - virtual bool has_attribute(GDMonoClass *p_attr_class); - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class); - virtual void fetch_attributes(); + virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; + void fetch_attributes(); _FORCE_INLINE_ int get_parameters_count() { return params_count; } _FORCE_INLINE_ ManagedType get_return_type() { return return_type; } diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index 04fd8b8e63f..5842e262416 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -80,24 +80,24 @@ bool GDMonoProperty::is_static() { return mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_STATIC; } -GDMonoClassMember::Visibility GDMonoProperty::get_visibility() { +IMonoClassMember::Visibility GDMonoProperty::get_visibility() { MonoMethod *prop_method = mono_property_get_get_method(mono_property); if (prop_method == NULL) prop_method = mono_property_get_set_method(mono_property); switch (mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) { case MONO_METHOD_ATTR_PRIVATE: - return GDMonoClassMember::PRIVATE; + return IMonoClassMember::PRIVATE; case MONO_METHOD_ATTR_FAM_AND_ASSEM: - return GDMonoClassMember::PROTECTED_AND_INTERNAL; + return IMonoClassMember::PROTECTED_AND_INTERNAL; case MONO_METHOD_ATTR_ASSEM: - return GDMonoClassMember::INTERNAL; + return IMonoClassMember::INTERNAL; case MONO_METHOD_ATTR_FAMILY: - return GDMonoClassMember::PROTECTED; + return IMonoClassMember::PROTECTED; case MONO_METHOD_ATTR_PUBLIC: - return GDMonoClassMember::PUBLIC; + return IMonoClassMember::PUBLIC; default: - ERR_FAIL_V(GDMonoClassMember::PRIVATE); + ERR_FAIL_V(IMonoClassMember::PRIVATE); } } diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index 934ce689041..d8a9f69ffb6 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -35,7 +35,7 @@ #include "gd_mono_class_member.h" #include "gd_mono_header.h" -class GDMonoProperty : public GDMonoClassMember { +class GDMonoProperty : public IMonoClassMember { GDMonoClass *owner; MonoProperty *mono_property; @@ -47,15 +47,15 @@ class GDMonoProperty : public GDMonoClassMember { MonoCustomAttrInfo *attributes; public: - virtual MemberType get_member_type() { return MEMBER_TYPE_PROPERTY; } + virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_PROPERTY; } - virtual StringName get_name() { return name; } + virtual StringName get_name() GD_FINAL { return name; } - virtual bool is_static(); - virtual Visibility get_visibility(); + virtual bool is_static() GD_FINAL; + virtual Visibility get_visibility() GD_FINAL; - virtual bool has_attribute(GDMonoClass *p_attr_class); - virtual MonoObject *get_attribute(GDMonoClass *p_attr_class); + virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL; + virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL; void fetch_attributes(); bool has_getter(); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 97a00a504d1..804bec811e2 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -565,7 +565,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { if (unexpected_exc) { GDMonoInternals::unhandled_exception(unexpected_exc); - _UNREACHABLE_(); + GD_UNREACHABLE(); } Vector _si; @@ -604,7 +604,7 @@ void debug_unhandled_exception(MonoException *p_exc) { ScriptDebugger::get_singleton()->idle_poll(); #endif GDMonoInternals::unhandled_exception(p_exc); // prints the exception as well - _UNREACHABLE_(); + GD_UNREACHABLE(); } void print_unhandled_exception(MonoException *p_exc) { @@ -615,7 +615,7 @@ void set_pending_exception(MonoException *p_exc) { #ifdef HAS_PENDING_EXCEPTIONS if (get_runtime_invoke_count() == 0) { debug_unhandled_exception(p_exc); - _UNREACHABLE_(); + GD_UNREACHABLE(); } if (!mono_runtime_set_pending_exception(p_exc, false)) { @@ -624,7 +624,7 @@ void set_pending_exception(MonoException *p_exc) { } #else debug_unhandled_exception(p_exc); - _UNREACHABLE_(); + GD_UNREACHABLE(); #endif } diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 6febc50a5fa..e88bf1ced97 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -44,7 +44,7 @@ #define UNLIKELY_UNHANDLED_EXCEPTION(m_exc) \ if (unlikely(m_exc != NULL)) { \ GDMonoUtils::debug_unhandled_exception(m_exc); \ - _UNREACHABLE_(); \ + GD_UNREACHABLE(); \ } namespace GDMonoUtils { @@ -214,7 +214,7 @@ void set_exception_message(MonoException *p_exc, String message); void debug_print_unhandled_exception(MonoException *p_exc); void debug_send_unhandled_exception_error(MonoException *p_exc); -_NO_RETURN_ void debug_unhandled_exception(MonoException *p_exc); +GD_NORETURN void debug_unhandled_exception(MonoException *p_exc); void print_unhandled_exception(MonoException *p_exc); /** diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 94e1193adfe..87295a98f25 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -31,39 +31,57 @@ #ifndef UTIL_MACROS_H #define UTIL_MACROS_H -#define _GD_VARNAME_CONCAT_B(m_ignore, m_name) m_name -#define _GD_VARNAME_CONCAT_A(m_a, m_b, m_c) _GD_VARNAME_CONCAT_B(hello there, m_a##m_b##m_c) -#define _GD_VARNAME_CONCAT(m_a, m_b, m_c) _GD_VARNAME_CONCAT_A(m_a, m_b, m_c) -#define GD_UNIQUE_NAME(m_name) _GD_VARNAME_CONCAT(m_name, _, __COUNTER__) +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(attr_token) 0 +#endif -// noreturn +#define _GD_VARNAME_CONCAT_B_(m_ignore, m_name) m_name +#define _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_B_(hello there, m_a##m_b##m_c) +#define _GD_VARNAME_CONCAT_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) +#define GD_UNIQUE_NAME(m_name) _GD_VARNAME_CONCAT_(m_name, _, __COUNTER__) -#if __cpp_static_assert +// static assert +// TODO: Get rid of this macro once we upgrade to C++11 + +#ifdef __cpp_static_assert #define GD_STATIC_ASSERT(m_cond) static_assert((m_cond), "Condition '" #m_cond "' failed") #else #define GD_STATIC_ASSERT(m_cond) typedef int GD_UNIQUE_NAME(godot_static_assert)[((m_cond) ? 1 : -1)] #endif -#undef _NO_RETURN_ +// final +// TODO: Get rid of this macro once we upgrade to C++11 -#ifdef __GNUC__ -#define _NO_RETURN_ __attribute__((noreturn)) -#elif _MSC_VER -#define _NO_RETURN_ __declspec(noreturn) +#if (__cplusplus >= 201103L) +#define GD_FINAL final #else -#error Platform or compiler not supported +#define GD_FINAL +#endif + +// noreturn +// TODO: Get rid of this macro once we upgrade to C++11 + +#if __has_cpp_attribute(deprecated) +#define GD_NORETURN [[noreturn]] +#elif defined(__GNUC__) +#define GD_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define GD_NORETURN __declspec(noreturn) +#else +#define GD_NORETURN +#pragma message "Macro GD_NORETURN will have no effect" #endif // unreachable #if defined(_MSC_VER) -#define _UNREACHABLE_() __assume(0) +#define GD_UNREACHABLE() __assume(0) #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 -#define _UNREACHABLE_() __builtin_unreachable() +#define GD_UNREACHABLE() __builtin_unreachable() #else -#define _UNREACHABLE_() \ - CRASH_NOW(); \ - do { \ +#define GD_UNREACHABLE() \ + CRASH_NOW(); \ + do { \ } while (true); #endif diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp index 5ed982200f6..f1362be2496 100644 --- a/modules/mono/utils/osx_utils.cpp +++ b/modules/mono/utils/osx_utils.cpp @@ -30,10 +30,10 @@ #include "osx_utils.h" -#include "core/print_string.h" - #ifdef OSX_ENABLED +#include "core/print_string.h" + #include #include diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index ea0193b8ed6..ea4f63b49c9 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -739,6 +739,11 @@ String OSUWP::get_environment(const String &p_var) const { return ""; }; +bool OSUWP::set_environment(const String &p_var, const String &p_value) const { + + return false; +} + String OSUWP::get_stdin_string(bool p_block) { return String(); diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 491c9bce03c..5475c4e60a0 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -213,6 +213,7 @@ public: virtual bool has_environment(const String &p_var) const; virtual String get_environment(const String &p_var) const; + virtual bool set_environment(const String &p_var, const String &p_value) const; virtual void set_clipboard(const String &p_text); virtual String get_clipboard() const; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 35f9d541ef1..9ae1be9afda 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2604,6 +2604,11 @@ String OS_Windows::get_environment(const String &p_var) const { return ""; } +bool OS_Windows::set_environment(const String &p_var, const String &p_value) const { + + return (bool)SetEnvironmentVariableW(p_var.c_str(), p_value.c_str()); +} + String OS_Windows::get_stdin_string(bool p_block) { if (p_block) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 4936a691206..771789c86b1 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -268,6 +268,7 @@ public: virtual bool has_environment(const String &p_var) const; virtual String get_environment(const String &p_var) const; + virtual bool set_environment(const String &p_var, const String &p_value) const; virtual void set_clipboard(const String &p_text); virtual String get_clipboard() const;