diff options
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/config.py | 42 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 43 | ||||
-rw-r--r-- | modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs | 84 | ||||
-rw-r--r-- | modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj | 4 | ||||
-rw-r--r-- | modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs | 6 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 169 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.h | 43 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 113 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.h | 5 | ||||
-rw-r--r-- | modules/mono/glue/builtin_types_glue.h | 30 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/GodotTaskScheduler.cs | 2 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Vector2.cs | 10 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Vector3.cs | 5 | ||||
-rw-r--r-- | modules/mono/mono_reg_utils.py | 2 | ||||
-rw-r--r-- | modules/mono/utils/mono_reg_utils.cpp | 2 |
15 files changed, 366 insertions, 194 deletions
diff --git a/modules/mono/config.py b/modules/mono/config.py index 831d849ea6..18d9c67795 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -59,9 +59,6 @@ def configure(env): mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0'] if env['platform'] == 'windows': - if mono_static: - raise RuntimeError('mono-static: Not supported on Windows') - if bits == '32': if os.getenv('MONO32_PREFIX'): mono_root = os.getenv('MONO32_PREFIX') @@ -81,24 +78,41 @@ def configure(env): env.Append(LIBPATH=mono_lib_path) env.Append(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0')) - mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib') + if mono_static: + lib_suffix = Environment()['LIBSUFFIX'] + mono_static_lib_name = 'libmono-static-sgen' - if not mono_lib_name: - raise RuntimeError('Could not find mono library in: ' + mono_lib_path) + if not os.path.isfile(os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix)): + raise RuntimeError('Could not find static mono library in: ' + mono_lib_path) - if os.getenv('VCINSTALLDIR'): - env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX']) + if env.msvc: + env.Append(LINKFLAGS=mono_static_lib_name + lib_suffix) + + env.Append(LINKFLAGS='Mincore' + lib_suffix) + env.Append(LINKFLAGS='msvcrt' + lib_suffix) + env.Append(LINKFLAGS='LIBCMT' + lib_suffix) + env.Append(LINKFLAGS='Psapi' + lib_suffix) + else: + env.Append(LIBS=mono_static_lib_name) else: - env.Append(LIBS=mono_lib_name) + mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib') + + if not mono_lib_name: + raise RuntimeError('Could not find mono library in: ' + mono_lib_path) + + if env.msvc: + env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX']) + else: + env.Append(LIBS=mono_lib_name) - mono_bin_path = os.path.join(mono_root, 'bin') + mono_bin_path = os.path.join(mono_root, 'bin') - mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll') + mono_dll_name = find_file_in_dir(mono_bin_path, mono_lib_names, extension='.dll') - if not mono_dll_name: - raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path) + if not mono_dll_name: + raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path) - copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll') + copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll') copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll') else: diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 1d0afa7f2d..161e62c81f 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -305,7 +305,7 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin " public override void _Ready()\n" " {\n" " // Called every time the node is added to the scene.\n" - " // Initialization here\n" + " // Initialization here.\n" " \n" " }\n" "\n" @@ -782,7 +782,7 @@ void CSharpLanguage::reload_assemblies_if_needed(bool p_soft_reload) { } if (Engine::get_singleton()->is_editor_hint()) { - EditorNode::get_singleton()->get_property_editor()->update_tree(); + EditorNode::get_singleton()->get_inspector()->update_tree(); NodeDock::singleton->update_lists(); } } @@ -1954,8 +1954,12 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Variant::Call ScriptInstance *CSharpScript::instance_create(Object *p_this) { - if (!valid) - return NULL; + if (!script_class) { + ERR_EXPLAIN("Cannot find class " + name + " for script " + get_path()); + ERR_FAIL_V(NULL); + } + + ERR_FAIL_COND_V(!valid, NULL); if (!tool && !ScriptServer::is_scripting_enabled()) { #ifdef TOOLS_ENABLED @@ -2045,20 +2049,15 @@ Error CSharpScript::reload(bool p_keep_state) { if (project_assembly) { script_class = project_assembly->get_object_derived_class(name); - if (!script_class) { - ERR_PRINTS("Cannot find class " + name + " for script " + get_path()); - } + valid = script_class != NULL; + + if (script_class) { #ifdef DEBUG_ENABLED - else if (OS::get_singleton()->is_stdout_verbose()) { OS::get_singleton()->print(String("Found class " + script_class->get_namespace() + "." + script_class->get_name() + " for script " + get_path() + "\n") .utf8()); - } #endif - valid = script_class != NULL; - - if (script_class) { tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute)); native = GDMonoUtils::get_class_native_base(script_class); @@ -2288,7 +2287,9 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p CRASH_COND(mono_domain_get() == NULL); #endif -#else +#endif + +#ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() && mono_domain_get() == NULL) { CRASH_COND(Thread::get_caller_id() == Thread::get_main_id()); @@ -2297,14 +2298,20 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p // because this may be called by one of the editor's worker threads. // Attach this thread temporarily to reload the script. - MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); - CRASH_COND(mono_thread == NULL); + if (SCRIPTS_DOMAIN) { + MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); + CRASH_COND(mono_thread == NULL); + script->reload(); + mono_thread_detach(mono_thread); + } + + } else { // just reload it normally +#endif script->reload(); - mono_thread_detach(mono_thread); - } else // just reload it normally +#ifdef TOOLS_ENABLED + } #endif - script->reload(); if (r_error) *r_error = OK; diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs index 04da0600cc..f3b4b66663 100644 --- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs @@ -16,24 +16,48 @@ namespace GodotSharpTools.Build private extern static void godot_icall_BuildInstance_ExitCallback(string solution, string config, int exitCode); [MethodImpl(MethodImplOptions.InternalCall)] - private extern static void godot_icall_BuildInstance_get_MSBuildInfo(ref string msbuildPath, ref string frameworkPath); + private extern static string godot_icall_BuildInstance_get_MSBuildPath(); + [MethodImpl(MethodImplOptions.InternalCall)] + private extern static string godot_icall_BuildInstance_get_FrameworkPath(); + [MethodImpl(MethodImplOptions.InternalCall)] + private extern static string godot_icall_BuildInstance_get_MonoWindowsBinDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private extern static bool godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); - private struct MSBuildInfo + private static string GetMSBuildPath() { - public string path; - public string frameworkPathOverride; + string msbuildPath = godot_icall_BuildInstance_get_MSBuildPath(); + + if (msbuildPath == null) + throw new FileNotFoundException("Cannot find the MSBuild executable."); + + return msbuildPath; } - private static MSBuildInfo GetMSBuildInfo() + private static string GetFrameworkPath() { - MSBuildInfo msbuildInfo = new MSBuildInfo(); + return godot_icall_BuildInstance_get_FrameworkPath(); + } - godot_icall_BuildInstance_get_MSBuildInfo(ref msbuildInfo.path, ref msbuildInfo.frameworkPathOverride); + private static string MonoWindowsBinDir + { + get + { + string monoWinBinDir = godot_icall_BuildInstance_get_MonoWindowsBinDir(); - if (msbuildInfo.path == null) - throw new FileNotFoundException("Cannot find the MSBuild executable."); + if (monoWinBinDir == null) + throw new FileNotFoundException("Cannot find the Windows Mono binaries directory."); + + return monoWinBinDir; + } + } - return msbuildInfo; + private static bool UsingMonoMSBuildOnWindows + { + get + { + return godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); + } } private string solution; @@ -54,25 +78,35 @@ namespace GodotSharpTools.Build public bool Build(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) { - MSBuildInfo msbuildInfo = GetMSBuildInfo(); - List<string> customPropertiesList = new List<string>(); if (customProperties != null) customPropertiesList.AddRange(customProperties); - if (msbuildInfo.frameworkPathOverride != null) - customPropertiesList.Add("FrameworkPathOverride=" + msbuildInfo.frameworkPathOverride); + string frameworkPath = GetFrameworkPath(); + + if (!string.IsNullOrEmpty(frameworkPath)) + customPropertiesList.Add("FrameworkPathOverride=" + frameworkPath); string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - ProcessStartInfo startInfo = new ProcessStartInfo(msbuildInfo.path, compilerArgs); + ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); // No console output, thanks startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; + if (UsingMonoMSBuildOnWindows) + { + // These environment variables are required for Mono's MSBuild to find the compilers. + // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. + string monoWinBinDir = MonoWindowsBinDir; + startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); + startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); + startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); + } + // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -98,25 +132,35 @@ namespace GodotSharpTools.Build if (process != null) throw new InvalidOperationException("Already in use"); - MSBuildInfo msbuildInfo = GetMSBuildInfo(); - List<string> customPropertiesList = new List<string>(); if (customProperties != null) customPropertiesList.AddRange(customProperties); - if (msbuildInfo.frameworkPathOverride.Length > 0) - customPropertiesList.Add("FrameworkPathOverride=" + msbuildInfo.frameworkPathOverride); + string frameworkPath = GetFrameworkPath(); + + if (!string.IsNullOrEmpty(frameworkPath)) + customPropertiesList.Add("FrameworkPathOverride=" + frameworkPath); string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - ProcessStartInfo startInfo = new ProcessStartInfo(msbuildInfo.path, compilerArgs); + ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); // No console output, thanks startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; + if (UsingMonoMSBuildOnWindows) + { + // These environment variables are required for Mono's MSBuild to find the compilers. + // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. + string monoWinBinDir = MonoWindowsBinDir; + startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); + startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); + startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); + } + // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj index 981083a3c2..1c8714e31d 100644 --- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj +++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj @@ -11,7 +11,7 @@ </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> + <DebugType>portable</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug</OutputPath> <DefineConstants>DEBUG;</DefineConstants> @@ -20,7 +20,7 @@ <ConsolePause>false</ConsolePause> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>full</DebugType> + <DebugType>portable</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release</OutputPath> <ErrorReport>prompt</ErrorReport> diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs index 6bf54a0156..1d863e6f61 100644 --- a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs +++ b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs @@ -70,7 +70,7 @@ namespace GodotSharpTools.Project var toolsGroup = root.AddPropertyGroup(); toolsGroup.Condition = " '$(Configuration)|$(Platform)' == 'Tools|AnyCPU' "; toolsGroup.AddProperty("DebugSymbols", "true"); - toolsGroup.AddProperty("DebugType", "full"); + toolsGroup.AddProperty("DebugType", "portable"); toolsGroup.AddProperty("Optimize", "false"); toolsGroup.AddProperty("DefineConstants", "DEBUG;TOOLS;"); toolsGroup.AddProperty("ErrorReport", "prompt"); @@ -148,7 +148,7 @@ namespace GodotSharpTools.Project var debugGroup = root.AddPropertyGroup(); debugGroup.Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "; debugGroup.AddProperty("DebugSymbols", "true"); - debugGroup.AddProperty("DebugType", "full"); + debugGroup.AddProperty("DebugType", "portable"); debugGroup.AddProperty("Optimize", "false"); debugGroup.AddProperty("DefineConstants", "DEBUG;"); debugGroup.AddProperty("ErrorReport", "prompt"); @@ -157,7 +157,7 @@ namespace GodotSharpTools.Project var releaseGroup = root.AddPropertyGroup(); releaseGroup.Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "; - releaseGroup.AddProperty("DebugType", "full"); + releaseGroup.AddProperty("DebugType", "portable"); releaseGroup.AddProperty("Optimize", "true"); releaseGroup.AddProperty("ErrorReport", "prompt"); releaseGroup.AddProperty("WarningLevel", "4"); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index a210b8e480..4c598d4f37 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -248,14 +248,14 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { if (imethod.is_virtual) continue; - const TypeInterface *return_type = _get_type_by_name_or_placeholder(imethod.return_type); + const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type); String im_sig; String im_unique_sig; if (p_itype.is_object_type) { im_sig += "IntPtr " CS_PARAM_METHODBIND ", "; - im_unique_sig += imethod.return_type.operator String() + ",IntPtr,IntPtr"; + im_unique_sig += imethod.return_type.cname.operator String() + ",IntPtr,IntPtr"; } im_sig += "IntPtr " CS_PARAM_INSTANCE; @@ -263,7 +263,7 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { // Get arguments information int i = 0; for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) { - const TypeInterface *arg_type = _get_type_by_name_or_placeholder(F->get().type); + const TypeInterface *arg_type = _get_type_or_placeholder(F->get().type); im_sig += ", "; im_sig += arg_type->im_type_in; @@ -730,7 +730,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output.push_back(INDENT1 "public "); - bool is_abstract = !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled' + bool is_abstract = itype.is_object_type && !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled' output.push_back(itype.is_singleton ? "static class " : (is_abstract ? "abstract class " : "class ")); output.push_back(itype.proxy_name); @@ -1069,12 +1069,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte } if (getter && setter) { - ERR_FAIL_COND_V(getter->return_type != setter->arguments.back()->get().type, ERR_BUG); + ERR_FAIL_COND_V(getter->return_type.cname != setter->arguments.back()->get().type.cname, ERR_BUG); } - StringName proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type; + const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type; - const TypeInterface *prop_itype = _get_type_by_name_or_null(proptype_name); + const TypeInterface *prop_itype = _get_type_or_null(proptype_name); ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(p_iprop.cname)); @@ -1122,9 +1122,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.push_back(getter->proxy_name + "("); if (p_iprop.index != -1) { const ArgumentInterface &idx_arg = getter->arguments.front()->get(); - if (idx_arg.type != name_cache.type_int) { + if (idx_arg.type.cname != name_cache.type_int) { // Assume the index parameter is an enum - const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type); + const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type); CRASH_COND(idx_arg_type == NULL); p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index)); } else { @@ -1139,9 +1139,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.push_back(setter->proxy_name + "("); if (p_iprop.index != -1) { const ArgumentInterface &idx_arg = setter->arguments.front()->get(); - if (idx_arg.type != name_cache.type_int) { + if (idx_arg.type.cname != name_cache.type_int) { // Assume the index parameter is an enum - const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type); + const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type); CRASH_COND(idx_arg_type == NULL); p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index) + ", "); } else { @@ -1158,7 +1158,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output) { - const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type); + const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type); String method_bind_field = "method_bind_" + itos(p_method_bind_count); @@ -1175,7 +1175,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf // Retrieve information from the arguments for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) { const ArgumentInterface &iarg = F->get(); - const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type); + const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); // Add the current arguments to the signature // If the argument has a default value which is not a constant, we will make it Nullable @@ -1328,21 +1328,19 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf const InternalCall *im_icall = match->value(); String im_call = im_icall->editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS; - im_call += "." + im_icall->name + "(" + icall_params + ");\n"; + im_call += "." + im_icall->name + "(" + icall_params + ")"; if (p_imethod.arguments.size()) p_output.push_back(cs_in_statements); if (return_type->cname == name_cache.type_void) { - p_output.push_back(im_call); + p_output.push_back(im_call + ";\n"); } else if (return_type->cs_out.empty()) { - p_output.push_back("return " + im_call); + p_output.push_back("return " + im_call + ";\n"); } else { - p_output.push_back(return_type->im_type_out); - p_output.push_back(" " LOCAL_RET " = "); - p_output.push_back(im_call); p_output.push_back(INDENT3); - p_output.push_back(sformat(return_type->cs_out, LOCAL_RET) + "\n"); + p_output.push_back(sformat(return_type->cs_out, im_call, return_type->cs_type, return_type->im_type_out)); + p_output.push_back("\n"); } p_output.push_back(CLOSE_BLOCK_L2); @@ -1540,9 +1538,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte if (p_imethod.is_virtual) return OK; // Ignore - bool ret_void = p_imethod.return_type == name_cache.type_void; + bool ret_void = p_imethod.return_type.cname == name_cache.type_void; - const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type); + const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type); String argc_str = itos(p_imethod.arguments.size()); @@ -1554,7 +1552,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte int i = 0; for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) { const ArgumentInterface &iarg = F->get(); - const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type); + const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type); String c_param_name = "arg" + itos(i + 1); @@ -1695,42 +1693,49 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte return OK; } -const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_null(const StringName &p_cname) { +const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(const TypeReference &p_typeref) { - const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_cname); + const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_typeref.cname); if (builtin_type_match) return &builtin_type_match->get(); - const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_cname); + const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_typeref.cname); if (obj_type_match) return &obj_type_match.get(); - const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_cname); + if (p_typeref.is_enum) { + const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_typeref.cname); - if (enum_match) - return &enum_match->get(); + if (enum_match) + return &enum_match->get(); + + // Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead. + const Map<StringName, TypeInterface>::Element *int_match = builtin_types.find(name_cache.type_int); + ERR_FAIL_NULL_V(int_match, NULL); + return &int_match->get(); + } return NULL; } -const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_placeholder(const StringName &p_cname) { +const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placeholder(const TypeReference &p_typeref) { - const TypeInterface *found = _get_type_by_name_or_null(p_cname); + const TypeInterface *found = _get_type_or_null(p_typeref); if (found) return found; - ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_cname.operator String()); + ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_typeref.cname.operator String()); - const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_cname); + const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname); if (match) return &match->get(); TypeInterface placeholder; - TypeInterface::create_placeholder_type(placeholder, p_cname); + TypeInterface::create_placeholder_type(placeholder, p_typeref.cname); return &placeholder_types.insert(placeholder.cname, placeholder)->get(); } @@ -1874,7 +1879,7 @@ void BindingsGenerator::_populate_object_type_interfaces() { // The method Object.free is registered as a virtual method, but without the virtual flag. // This is because this method is not supposed to be overridden, but called. // We assume the return type is void. - imethod.return_type = name_cache.type_void; + imethod.return_type.cname = name_cache.type_void; // Actually, more methods like this may be added in the future, // which could actually will return something different. @@ -1889,21 +1894,22 @@ void BindingsGenerator::_populate_object_type_interfaces() { } else { ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name); } - } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant? - imethod.return_type = return_info.class_name; + } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + imethod.return_type.cname = return_info.class_name; + imethod.return_type.is_enum = true; } else if (return_info.class_name != StringName()) { - imethod.return_type = return_info.class_name; + imethod.return_type.cname = return_info.class_name; } else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { - imethod.return_type = return_info.hint_string; + imethod.return_type.cname = return_info.hint_string; } else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - imethod.return_type = name_cache.type_Variant; + imethod.return_type.cname = name_cache.type_Variant; } else if (return_info.type == Variant::NIL) { - imethod.return_type = name_cache.type_void; + imethod.return_type.cname = name_cache.type_void; } else { - imethod.return_type = Variant::get_type_name(return_info.type); + imethod.return_type.cname = Variant::get_type_name(return_info.type); } - if (!itype.requires_collections && imethod.return_type == name_cache.type_Dictionary) + if (!itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary) itype.requires_collections = true; for (int i = 0; i < argc; i++) { @@ -1912,21 +1918,22 @@ void BindingsGenerator::_populate_object_type_interfaces() { ArgumentInterface iarg; iarg.name = arginfo.name; - if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant? - iarg.type = arginfo.class_name; + if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + iarg.type.cname = arginfo.class_name; + iarg.type.is_enum = true; } else if (arginfo.class_name != StringName()) { - iarg.type = arginfo.class_name; + iarg.type.cname = arginfo.class_name; } else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - iarg.type = arginfo.hint_string; + iarg.type.cname = arginfo.hint_string; } else if (arginfo.type == Variant::NIL) { - iarg.type = name_cache.type_Variant; + iarg.type.cname = name_cache.type_Variant; } else { - iarg.type = Variant::get_type_name(arginfo.type); + iarg.type.cname = Variant::get_type_name(arginfo.type); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); - if (!itype.requires_collections && iarg.type == name_cache.type_Dictionary) + if (!itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary) itype.requires_collections = true; if (m && m->has_default_argument(i)) { @@ -1938,7 +1945,7 @@ void BindingsGenerator::_populate_object_type_interfaces() { if (imethod.is_vararg) { ArgumentInterface ivararg; - ivararg.type = name_cache.type_VarArg; + ivararg.type.cname = name_cache.type_VarArg; ivararg.name = "@args"; imethod.add_argument(ivararg); } @@ -2023,17 +2030,11 @@ void BindingsGenerator::_populate_object_type_interfaces() { itype.enums.push_back(ienum); TypeInterface enum_itype; + enum_itype.is_enum = true; enum_itype.name = itype.name + "." + String(*k); enum_itype.cname = StringName(enum_itype.name); enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name; - enum_itype.c_arg_in = "&%s"; - enum_itype.c_type = "int"; - enum_itype.c_type_in = "int"; - enum_itype.c_type_out = "int"; - enum_itype.cs_type = enum_itype.proxy_name; - enum_itype.im_type_in = enum_itype.proxy_name; - enum_itype.im_type_out = enum_itype.proxy_name; - enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[enum_itype.proxy_name]; + TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); } @@ -2068,7 +2069,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg switch (p_val.get_type()) { case Variant::NIL: - if (ClassDB::class_exists(r_iarg.type)) { + if (ClassDB::class_exists(r_iarg.type.cname)) { // Object type r_iarg.default_argument = "null"; } else { @@ -2081,7 +2082,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg r_iarg.default_argument = bool(p_val) ? "true" : "false"; break; case Variant::INT: - if (r_iarg.type != name_cache.type_int) { + if (r_iarg.type.cname != name_cache.type_int) { r_iarg.default_argument = "(%s)" + r_iarg.default_argument; } break; @@ -2142,7 +2143,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg default: {} } - if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type == name_cache.type_Variant && r_iarg.default_argument != "null") + if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null") r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; } @@ -2161,7 +2162,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_arg_in = "&%s_in"; \ itype.c_type_in = m_type_in; \ itype.cs_in = "ref %s"; \ - itype.cs_out = "return (" #m_type ")%0;"; \ + itype.cs_out = "return (%1)%0;"; \ itype.im_type_out = "object"; \ builtin_types.insert(itype.cname, itype); \ } @@ -2256,7 +2257,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.c_type + "*"; itype.cs_type = itype.proxy_name; itype.cs_in = "NodePath." CS_SMETHOD_GETINSTANCE "(%0)"; - itype.cs_out = "return new NodePath(%0);"; + itype.cs_out = "return new %1(%0);"; itype.im_type_in = "IntPtr"; itype.im_type_out = "IntPtr"; _populate_builtin_type(itype, Variant::NODE_PATH); @@ -2279,7 +2280,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.c_type + "*"; itype.cs_type = itype.proxy_name; itype.cs_in = "RID." CS_SMETHOD_GETINSTANCE "(%0)"; - itype.cs_out = "return new RID(%0);"; + itype.cs_out = "return new %1(%0);"; itype.im_type_in = "IntPtr"; itype.im_type_out = "IntPtr"; _populate_builtin_type(itype, Variant::_RID); @@ -2408,11 +2409,11 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant:: iarg.name = pi.name; if (pi.type == Variant::NIL) - iarg.type = name_cache.type_Variant; + iarg.type.cname = name_cache.type_Variant; else - iarg.type = Variant::get_type_name(pi.type); + iarg.type.cname = Variant::get_type_name(pi.type); - if (!r_itype.requires_collections && iarg.type == name_cache.type_Dictionary) + if (!r_itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary) r_itype.requires_collections = true; if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0) @@ -2423,12 +2424,12 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant:: if (mi.return_val.type == Variant::NIL) { if (mi.return_val.name != "") - imethod.return_type = name_cache.type_Variant; + imethod.return_type.cname = name_cache.type_Variant; } else { - imethod.return_type = Variant::get_type_name(mi.return_val.type); + imethod.return_type.cname = Variant::get_type_name(mi.return_val.type); } - if (!r_itype.requires_collections && imethod.return_type == name_cache.type_Dictionary) + if (!r_itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary) r_itype.requires_collections = true; if (r_itype.class_doc) { @@ -2494,13 +2495,11 @@ void BindingsGenerator::_populate_global_constants() { EnumInterface &ienum = E->get(); TypeInterface enum_itype; - enum_itype = TypeInterface::create_value_type(ienum.cname); - enum_itype.c_arg_in = "&%s"; - enum_itype.c_type = "int"; - enum_itype.c_type_in = "int"; - enum_itype.c_type_out = "int"; - enum_itype.im_type_in = enum_itype.name; - enum_itype.im_type_out = enum_itype.name; + enum_itype.is_enum = true; + enum_itype.name = ienum.cname.operator String(); + enum_itype.cname = ienum.cname; + enum_itype.proxy_name = enum_itype.name; + TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); ienum.prefix = _determine_enum_prefix(ienum); @@ -2521,15 +2520,13 @@ void BindingsGenerator::_populate_global_constants() { hardcoded_enums.push_back("Vector3.Axis"); for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) - // Here, we are assuming core types do not begin with underscore + // Here, we assume core types do not begin with underscore TypeInterface enum_itype; - enum_itype = TypeInterface::create_value_type(E->get()); - enum_itype.c_arg_in = "&%s"; - enum_itype.c_type = "int"; - enum_itype.c_type_in = "int"; - enum_itype.c_type_out = "int"; - enum_itype.im_type_in = enum_itype.name; - enum_itype.im_type_out = enum_itype.name; + enum_itype.is_enum = true; + enum_itype.name = E->get().operator String(); + enum_itype.cname = E->get(); + enum_itype.proxy_name = enum_itype.name; + TypeInterface::postsetup_enum_type(enum_itype); enum_types.insert(enum_itype.cname, enum_itype); } } diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index f6194139af..5b33a0e53f 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -81,6 +81,15 @@ class BindingsGenerator { const DocData::PropertyDoc *prop_doc; }; + struct TypeReference { + StringName cname; + bool is_enum; + + TypeReference() { + is_enum = false; + } + }; + struct ArgumentInterface { enum DefaultParamMode { CONSTANT, @@ -88,7 +97,8 @@ class BindingsGenerator { NULLABLE_REF }; - StringName type; + TypeReference type; + String name; String default_argument; DefaultParamMode def_param_mode; @@ -110,7 +120,7 @@ class BindingsGenerator { /** * [TypeInterface::name] of the return type */ - StringName return_type; + TypeReference return_type; /** * Determines if the method has a variable number of arguments (VarArg) @@ -146,7 +156,7 @@ class BindingsGenerator { } MethodInterface() { - return_type = BindingsGenerator::get_singleton()->name_cache.type_void; + return_type.cname = BindingsGenerator::get_singleton()->name_cache.type_void; is_vararg = false; is_virtual = false; requires_object_call = false; @@ -175,6 +185,7 @@ class BindingsGenerator { ClassDB::APIType api_type; + bool is_enum; bool is_object_type; bool is_singleton; bool is_reference; @@ -276,7 +287,9 @@ class BindingsGenerator { * One or more statements that determine how a variable of this type is returned from a method. * It must contain the return statement(s). * Formatting elements: - * %0 or %s: name of the variable to be returned + * %0: internal method call statement + * %1: [cs_type] of the return type + * %2: [im_type_out] of the return type */ String cs_out; @@ -293,8 +306,6 @@ class BindingsGenerator { /** * Type used for the return type of internal call methods. - * If [cs_out] is not empty and the method return type is not void, - * it is also used for the type of the return variable. */ String im_type_out; @@ -379,10 +390,24 @@ class BindingsGenerator { r_itype.im_type_out = r_itype.proxy_name; } + static void postsetup_enum_type(TypeInterface &r_enum_itype) { + r_enum_itype.c_arg_in = "&%s"; + r_enum_itype.c_type = "int"; + r_enum_itype.c_type_in = "int"; + r_enum_itype.c_type_out = "int"; + r_enum_itype.cs_type = r_enum_itype.proxy_name; + r_enum_itype.cs_in = "(int)%s"; + r_enum_itype.cs_out = "return (%1)%0;"; + r_enum_itype.im_type_in = "int"; + r_enum_itype.im_type_out = "int"; + r_enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[r_enum_itype.proxy_name]; + } + TypeInterface() { api_type = ClassDB::API_NONE; + is_enum = false; is_object_type = false; is_singleton = false; is_reference = false; @@ -492,6 +517,8 @@ class BindingsGenerator { return "Ref"; else if (p_type.is_object_type) return "Obj"; + else if (p_type.is_enum) + return "int"; return p_type.name; } @@ -501,8 +528,8 @@ class BindingsGenerator { void _generate_header_icalls(); void _generate_method_icalls(const TypeInterface &p_itype); - const TypeInterface *_get_type_by_name_or_null(const StringName &p_cname); - const TypeInterface *_get_type_by_name_or_placeholder(const StringName &p_cname); + const TypeInterface *_get_type_or_null(const TypeReference &p_typeref); + const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref); void _default_argument_from_variant(const Variant &p_val, ArgumentInterface &r_iarg); void _populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype); diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 2f2b5768db..ef54046f12 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -39,6 +39,10 @@ #include "bindings_generator.h" #include "godotsharp_editor.h" +#define PROP_NAME_MSBUILD_MONO "MSBuild (Mono)" +#define PROP_NAME_MSBUILD_VS "MSBuild (VS Build Tools)" +#define PROP_NAME_XBUILD "xbuild (Deprecated)" + void godot_icall_BuildInstance_ExitCallback(MonoString *p_solution, MonoString *p_config, int p_exit_code) { String solution = GDMonoMarshal::mono_string_to_godot(p_solution); @@ -76,46 +80,42 @@ String _find_build_engine_on_unix(const String &p_name) { } #endif -void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, MonoString **r_framework_path) { +MonoString *godot_icall_BuildInstance_get_MSBuildPath() { GodotSharpBuilds::BuildTool build_tool = GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool"))); #if defined(WINDOWS_ENABLED) switch (build_tool) { - case GodotSharpBuilds::MSBUILD: { + case GodotSharpBuilds::MSBUILD_VS: { static String msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path(); if (msbuild_tools_path.length()) { if (!msbuild_tools_path.ends_with("\\")) msbuild_tools_path += "\\"; - // FrameworkPathOverride - const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); - if (mono_reg_info.assembly_dir.length()) { - *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); - - String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5"); - *r_framework_path = GDMonoMarshal::mono_string_from_godot(framework_path); - } else { - ERR_PRINT("Cannot find Mono's assemblies directory in the registry"); - } - - return; + return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); } if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print("Cannot find System's MSBuild. Trying with Mono's...\n"); - } // fall through + OS::get_singleton()->print("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Trying with '" PROP_NAME_MSBUILD_MONO "'...\n"); + } // FALL THROUGH case GodotSharpBuilds::MSBUILD_MONO: { String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat"); if (!FileAccess::exists(msbuild_path)) { - WARN_PRINTS("Cannot find msbuild ('mono/builds/build_tool'). Tried with path: " + msbuild_path); + WARN_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_MONO "'. Tried with path: " + msbuild_path); } - *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(msbuild_path); + return GDMonoMarshal::mono_string_from_godot(msbuild_path); + } break; + case GodotSharpBuilds::XBUILD: { + String xbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("xbuild.bat"); - return; + if (!FileAccess::exists(xbuild_path)) { + WARN_PRINTS("Cannot find executable for '" PROP_NAME_XBUILD "'. Tried with path: " + xbuild_path); + } + + return GDMonoMarshal::mono_string_from_godot(xbuild_path); } break; default: ERR_EXPLAIN("You don't deserve to live"); @@ -125,31 +125,74 @@ void godot_icall_BuildInstance_get_MSBuildInfo(MonoString **r_msbuild_path, Mono static String msbuild_path = _find_build_engine_on_unix("msbuild"); static String xbuild_path = _find_build_engine_on_unix("xbuild"); - if (build_tool != GodotSharpBuilds::XBUILD) { - if (msbuild_path.empty()) { - WARN_PRINT("Cannot find msbuild ('mono/builds/build_tool')."); + if (build_tool == GodotSharpBuilds::XBUILD) { + if (xbuild_path.empty()) { + WARN_PRINT("Cannot find binary for '" PROP_NAME_XBUILD "'"); return; } } else { - if (xbuild_path.empty()) { - WARN_PRINT("Cannot find xbuild ('mono/builds/build_tool')."); + if (msbuild_path.empty()) { + WARN_PRINT("Cannot find binary for '" PROP_NAME_MSBUILD_MONO "'"); return; } } - *r_msbuild_path = GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path); + return GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path); +#else + (void)build_tool; // UNUSED + + ERR_EXPLAIN("Not implemented on this platform"); + ERR_FAIL_V(NULL); +#endif +} + +MonoString *godot_icall_BuildInstance_get_FrameworkPath() { + +#if defined(WINDOWS_ENABLED) + const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); + if (mono_reg_info.assembly_dir.length()) { + String framework_path = path_join(mono_reg_info.assembly_dir, "mono", "4.5"); + return GDMonoMarshal::mono_string_from_godot(framework_path); + } - return; + ERR_EXPLAIN("Cannot find Mono's assemblies directory in the registry"); + ERR_FAIL_V(NULL); #else - ERR_PRINT("Not implemented on this platform"); - return; + return NULL; +#endif +} + +MonoString *godot_icall_BuildInstance_get_MonoWindowsBinDir() { + +#if defined(WINDOWS_ENABLED) + const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); + if (mono_reg_info.bin_dir.length()) { + return GDMonoMarshal::mono_string_from_godot(mono_reg_info.bin_dir); + } + + ERR_EXPLAIN("Cannot find Mono's binaries directory in the registry"); + ERR_FAIL_V(NULL); +#else + return NULL; +#endif +} + +MonoBoolean godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows() { + +#if defined(WINDOWS_ENABLED) + return GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool"))) == GodotSharpBuilds::MSBUILD_MONO; +#else + return false; #endif } void GodotSharpBuilds::_register_internal_calls() { mono_add_internal_call("GodotSharpTools.Build.BuildSystem::godot_icall_BuildInstance_ExitCallback", (void *)godot_icall_BuildInstance_ExitCallback); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildInfo", (void *)godot_icall_BuildInstance_get_MSBuildInfo); + mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildPath", (void *)godot_icall_BuildInstance_get_MSBuildPath); + mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_FrameworkPath", (void *)godot_icall_BuildInstance_get_FrameworkPath); + mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MonoWindowsBinDir", (void *)godot_icall_BuildInstance_get_MonoWindowsBinDir); + mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows", (void *)godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows); } void GodotSharpBuilds::show_build_error_dialog(const String &p_message) { @@ -386,20 +429,14 @@ GodotSharpBuilds::GodotSharpBuilds() { // Build tool settings EditorSettings *ed_settings = EditorSettings::get_singleton(); -#ifdef WINDOWS_ENABLED - // TODO: Default to MSBUILD_MONO if its csc.exe issue is fixed in the installed mono version - EDITOR_DEF("mono/builds/build_tool", MSBUILD); -#else EDITOR_DEF("mono/builds/build_tool", MSBUILD_MONO); -#endif ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/builds/build_tool", PROPERTY_HINT_ENUM, + PROP_NAME_MSBUILD_MONO #ifdef WINDOWS_ENABLED - "MSBuild (Mono),MSBuild (System)" -#else - "MSBuild (Mono),xbuild (Deprecated)" + "," PROP_NAME_MSBUILD_VS #endif - )); + "," PROP_NAME_XBUILD)); } GodotSharpBuilds::~GodotSharpBuilds() { diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h index 27b771e324..4afc284d45 100644 --- a/modules/mono/editor/godotsharp_builds.h +++ b/modules/mono/editor/godotsharp_builds.h @@ -68,10 +68,9 @@ public: enum BuildTool { MSBUILD_MONO, #ifdef WINDOWS_ENABLED - MSBUILD -#else - XBUILD // Deprecated + MSBUILD_VS, #endif + XBUILD // Deprecated }; _FORCE_INLINE_ static GodotSharpBuilds *get_singleton() { return singleton; } diff --git a/modules/mono/glue/builtin_types_glue.h b/modules/mono/glue/builtin_types_glue.h index 460de84b65..ef9f152682 100644 --- a/modules/mono/glue/builtin_types_glue.h +++ b/modules/mono/glue/builtin_types_glue.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* builtin_types_glue.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef BUILTIN_TYPES_GLUE_H #define BUILTIN_TYPES_GLUE_H diff --git a/modules/mono/glue/cs_files/GodotTaskScheduler.cs b/modules/mono/glue/cs_files/GodotTaskScheduler.cs index 6bf25a89d2..3d23ec10f1 100644 --- a/modules/mono/glue/cs_files/GodotTaskScheduler.cs +++ b/modules/mono/glue/cs_files/GodotTaskScheduler.cs @@ -14,6 +14,7 @@ namespace Godot public GodotTaskScheduler() { Context = new GodotSynchronizationContext(); + SynchronizationContext.SetSynchronizationContext(Context); } protected sealed override void QueueTask(Task task) @@ -57,7 +58,6 @@ namespace Godot public void Activate() { - SynchronizationContext.SetSynchronizationContext(Context); ExecuteQueuedTasks(); Context.ExecutePendingContinuations(); } diff --git a/modules/mono/glue/cs_files/Vector2.cs b/modules/mono/glue/cs_files/Vector2.cs index cc2cda82fb..9bc40cf8df 100644 --- a/modules/mono/glue/cs_files/Vector2.cs +++ b/modules/mono/glue/cs_files/Vector2.cs @@ -97,6 +97,11 @@ namespace Godot return -Reflect(n); } + public Vector2 Ceil() + { + return new Vector2(Mathf.Ceil(x), Mathf.Ceil(y)); + } + public Vector2 Clamped(real_t length) { var v = this; @@ -190,6 +195,11 @@ namespace Godot return new Vector2(Mathf.Cos(rads), Mathf.Sin(rads)) * Length(); } + public Vector2 Round() + { + return new Vector2(Mathf.Round(x), Mathf.Round(y)); + } + public void Set(real_t x, real_t y) { this.x = x; diff --git a/modules/mono/glue/cs_files/Vector3.cs b/modules/mono/glue/cs_files/Vector3.cs index 0a71f3fa4d..57e4494f7e 100644 --- a/modules/mono/glue/cs_files/Vector3.cs +++ b/modules/mono/glue/cs_files/Vector3.cs @@ -219,6 +219,11 @@ namespace Godot return 2.0f * n * Dot(n) - this; } + public Vector3 Round() + { + return new Vector3(Mathf.Round(x), Mathf.Round(y), Mathf.Round(z)); + } + public Vector3 Rotated(Vector3 axis, real_t phi) { return new Basis(axis, phi).Xform(this); diff --git a/modules/mono/mono_reg_utils.py b/modules/mono/mono_reg_utils.py index 8ddddb3a24..9c188d07a7 100644 --- a/modules/mono/mono_reg_utils.py +++ b/modules/mono/mono_reg_utils.py @@ -75,7 +75,7 @@ def find_msbuild_tools_path_reg(): vswhere = os.getenv('PROGRAMFILES') vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe' - vswhere_args = ['-latest', '-requires', 'Microsoft.Component.MSBuild'] + vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild'] try: lines = subprocess.check_output([vswhere] + vswhere_args).splitlines() diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp index 9bb8da8ac0..7b23cd7579 100644 --- a/modules/mono/utils/mono_reg_utils.cpp +++ b/modules/mono/utils/mono_reg_utils.cpp @@ -174,6 +174,8 @@ String find_msbuild_tools_path() { List<String> vswhere_args; vswhere_args.push_back("-latest"); + vswhere_args.push_back("-products"); + vswhere_args.push_back("*"); vswhere_args.push_back("-requires"); vswhere_args.push_back("Microsoft.Component.MSBuild"); |