summaryrefslogtreecommitdiff
path: root/modules/mono
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono')
-rw-r--r--modules/mono/config.py42
-rw-r--r--modules/mono/csharp_script.cpp43
-rw-r--r--modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs84
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj4
-rw-r--r--modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs6
-rw-r--r--modules/mono/editor/bindings_generator.cpp169
-rw-r--r--modules/mono/editor/bindings_generator.h43
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp113
-rw-r--r--modules/mono/editor/godotsharp_builds.h5
-rw-r--r--modules/mono/glue/builtin_types_glue.h30
-rw-r--r--modules/mono/glue/cs_files/GodotTaskScheduler.cs2
-rw-r--r--modules/mono/glue/cs_files/Vector2.cs10
-rw-r--r--modules/mono/glue/cs_files/Vector3.cs5
-rw-r--r--modules/mono/mono_reg_utils.py2
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp2
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");