summaryrefslogtreecommitdiff
path: root/modules/mono/editor
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/editor')
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs18
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs16
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs12
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs16
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs18
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs4
-rw-r--r--modules/mono/editor/bindings_generator.cpp52
-rw-r--r--modules/mono/editor/bindings_generator.h1
-rw-r--r--modules/mono/editor/code_completion.cpp4
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp2
-rw-r--r--modules/mono/editor/hostfxr_resolver.cpp335
-rw-r--r--modules/mono/editor/hostfxr_resolver.h45
-rw-r--r--modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs4
-rw-r--r--modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs6
-rw-r--r--modules/mono/editor/script_templates/Node/default.cs2
-rw-r--r--modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs14
-rw-r--r--modules/mono/editor/semver.cpp149
-rw-r--r--modules/mono/editor/semver.h106
30 files changed, 752 insertions, 103 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 59ce1da17b..0459257106 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -62,7 +62,7 @@
</PropertyGroup>
<PropertyGroup>
- <GodotRealTIsDouble Condition=" '$(GodotRealTIsDouble)' == '' ">false</GodotRealTIsDouble>
+ <GodotFloat64 Condition=" '$(GodotFloat64)' == '' ">false</GodotFloat64>
</PropertyGroup>
<!-- Godot DefineConstants. -->
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
index aad4ea4553..bff9760b32 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.targets
@@ -10,9 +10,9 @@
<!--
Define constant to determine whether the real_t type in Godot is double precision or not.
By default this is false, like the official Godot builds. If someone is using a custom
- Godot build where real_t is double, they can override the GodotRealTIsDouble property.
+ Godot build where real_t is double, they can override the GodotFloat64 property.
-->
- <DefineConstants Condition=" '$(GodotRealTIsDouble)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants>
+ <DefineConstants Condition=" '$(GodotFloat64)' == 'true' ">GODOT_REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<!-- C# source generators -->
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs
index a1667dbb8f..e43a3469ae 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ScriptBoilerplate.cs
@@ -7,7 +7,7 @@ namespace Godot.SourceGenerators.Sample
private NodePath _nodePath;
private int _velocity;
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
_ = delta;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
index 54da6218f3..7ec3f88e5d 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
@@ -27,7 +27,8 @@ namespace GodotPlugins.Game
internal static partial class Main
{
[UnmanagedCallersOnly(EntryPoint = ""godotsharp_game_main_init"")]
- private static godot_bool InitializeFromGameProject(IntPtr godotDllHandle, IntPtr outManagedCallbacks)
+ private static godot_bool InitializeFromGameProject(IntPtr godotDllHandle, IntPtr outManagedCallbacks,
+ IntPtr unmanagedCallbacks, int unmanagedCallbacksSize)
{
try
{
@@ -37,6 +38,8 @@ namespace GodotPlugins.Game
NativeLibrary.SetDllImportResolver(coreApiAssembly, dllImportResolver);
+ NativeFuncs.Initialize(unmanagedCallbacks, unmanagedCallbacksSize);
+
ManagedCallbacks.Create(outManagedCallbacks);
ScriptManagerBridge.LookupScriptsInAssembly(typeof(GodotPlugins.Game.Main).Assembly);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs
index 7aaadb27be..98ca534c66 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs
@@ -39,6 +39,11 @@ namespace Godot.SourceGenerators
for (int i = 0; i < typeArgListSyntax.Arguments.Count; i++)
{
var typeSyntax = typeArgListSyntax.Arguments[i];
+
+ // Ignore omitted type arguments, e.g.: List<>, Dictionary<,>, etc
+ if (typeSyntax is OmittedTypeArgumentSyntax)
+ continue;
+
var typeSymbol = sm.GetSymbolInfo(typeSyntax).Symbol as ITypeSymbol;
Debug.Assert(typeSymbol != null);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
index 5ac4f4a47e..1ee31eb1a9 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
@@ -133,7 +133,9 @@ namespace Godot.SourceGenerators
.Distinct(new MethodOverloadEqualityComparer())
.ToArray();
- source.Append(" private partial class GodotInternal {\n");
+ source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
+
+ source.Append($" public new class MethodName : {symbol.BaseType.FullQualifiedName()}.MethodName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
@@ -144,7 +146,7 @@ namespace Godot.SourceGenerators
foreach (string methodName in distinctMethodNames)
{
- source.Append(" public static readonly StringName MethodName_");
+ source.Append(" public new static readonly StringName ");
source.Append(methodName);
source.Append(" = \"");
source.Append(methodName);
@@ -157,8 +159,6 @@ namespace Godot.SourceGenerators
if (godotClassMethods.Length > 0)
{
- source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
-
const string listType = "System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
source.Append(" internal new static ")
@@ -179,10 +179,10 @@ namespace Godot.SourceGenerators
source.Append(" return methods;\n");
source.Append(" }\n");
-
- source.Append("#pragma warning restore CS0109\n");
}
+ source.Append("#pragma warning restore CS0109\n");
+
// Generate InvokeGodotClassMethod
if (godotClassMethods.Length > 0)
@@ -242,7 +242,7 @@ namespace Godot.SourceGenerators
private static void AppendMethodInfo(StringBuilder source, MethodInfo methodInfo)
{
- source.Append(" methods.Add(new(name: GodotInternal.MethodName_")
+ source.Append(" methods.Add(new(name: MethodName.")
.Append(methodInfo.Name)
.Append(", returnVal: ");
@@ -350,7 +350,7 @@ namespace Godot.SourceGenerators
source.Append(" ");
if (!isFirstEntry)
source.Append("else ");
- source.Append("if (method == GodotInternal.MethodName_");
+ source.Append("if (method == MethodName.");
source.Append(methodName);
source.Append(") {\n return true;\n }\n");
}
@@ -362,7 +362,7 @@ namespace Godot.SourceGenerators
{
string methodName = method.Method.Name;
- source.Append(" if (method == GodotInternal.MethodName_");
+ source.Append(" if (method == MethodName.");
source.Append(methodName);
source.Append(" && argCount == ");
source.Append(method.ParamTypes.Length);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
index fc46d82dff..b331e2e794 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -122,14 +122,16 @@ namespace Godot.SourceGenerators
var godotClassProperties = propertySymbols.WhereIsGodotCompatibleType(typeCache).ToArray();
var godotClassFields = fieldSymbols.WhereIsGodotCompatibleType(typeCache).ToArray();
- source.Append(" private partial class GodotInternal {\n");
+ source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
+
+ source.Append($" public new class PropertyName : {symbol.BaseType.FullQualifiedName()}.PropertyName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
foreach (var property in godotClassProperties)
{
string propertyName = property.PropertySymbol.Name;
- source.Append(" public static readonly StringName PropName_");
+ source.Append(" public new static readonly StringName ");
source.Append(propertyName);
source.Append(" = \"");
source.Append(propertyName);
@@ -139,7 +141,7 @@ namespace Godot.SourceGenerators
foreach (var field in godotClassFields)
{
string fieldName = field.FieldSymbol.Name;
- source.Append(" public static readonly StringName PropName_");
+ source.Append(" public new static readonly StringName ");
source.Append(fieldName);
source.Append(" = \"");
source.Append(fieldName);
@@ -214,8 +216,6 @@ namespace Godot.SourceGenerators
// Generate GetGodotPropertyList
- source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
-
string dictionaryType = "System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>";
source.Append(" internal new static ")
@@ -289,7 +289,7 @@ namespace Godot.SourceGenerators
if (!isFirstEntry)
source.Append("else ");
- source.Append("if (name == GodotInternal.PropName_")
+ source.Append("if (name == PropertyName.")
.Append(propertyMemberName)
.Append(") {\n")
.Append(" ")
@@ -313,7 +313,7 @@ namespace Godot.SourceGenerators
if (!isFirstEntry)
source.Append("else ");
- source.Append("if (name == GodotInternal.PropName_")
+ source.Append("if (name == PropertyName.")
.Append(propertyMemberName)
.Append(") {\n")
.Append(" value = ")
@@ -342,7 +342,7 @@ namespace Godot.SourceGenerators
{
source.Append(" properties.Add(new(type: (Godot.Variant.Type)")
.Append((int)propertyInfo.Type)
- .Append(", name: GodotInternal.PropName_")
+ .Append(", name: PropertyName.")
.Append(propertyInfo.Name)
.Append(", hint: (Godot.PropertyHint)")
.Append((int)propertyInfo.Hint)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index c7745391d0..65dadcb801 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -243,7 +243,7 @@ namespace Godot.SourceGenerators
source.Append(" = ");
source.Append(exportedMember.Value ?? "default");
source.Append(";\n");
- source.Append(" values.Add(GodotInternal.PropName_");
+ source.Append(" values.Add(PropertyName.");
source.Append(exportedMember.Name);
source.Append(", ");
source.Append(defaultValueLocalName);
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
index 39a99ff8ba..a40220565f 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -159,7 +159,7 @@ namespace Godot.SourceGenerators
{
string propertyName = property.PropertySymbol.Name;
- source.Append(" info.AddProperty(GodotInternal.PropName_")
+ source.Append(" info.AddProperty(PropertyName.")
.Append(propertyName)
.Append(", ")
.AppendManagedToVariantExpr(string.Concat("this.", propertyName), property.Type)
@@ -172,7 +172,7 @@ namespace Godot.SourceGenerators
{
string fieldName = field.FieldSymbol.Name;
- source.Append(" info.AddProperty(GodotInternal.PropName_")
+ source.Append(" info.AddProperty(PropertyName.")
.Append(fieldName)
.Append(", ")
.AppendManagedToVariantExpr(string.Concat("this.", fieldName), field.Type)
@@ -185,7 +185,7 @@ namespace Godot.SourceGenerators
{
string signalName = signalDelegate.Name;
- source.Append(" info.AddSignalEventDelegate(GodotInternal.SignalName_")
+ source.Append(" info.AddSignalEventDelegate(SignalName.")
.Append(signalName)
.Append(", this.backing_")
.Append(signalName)
@@ -204,7 +204,7 @@ namespace Godot.SourceGenerators
{
string propertyName = property.PropertySymbol.Name;
- source.Append(" if (info.TryGetProperty(GodotInternal.PropName_")
+ source.Append(" if (info.TryGetProperty(PropertyName.")
.Append(propertyName)
.Append(", out var _value_")
.Append(propertyName)
@@ -223,7 +223,7 @@ namespace Godot.SourceGenerators
{
string fieldName = field.FieldSymbol.Name;
- source.Append(" if (info.TryGetProperty(GodotInternal.PropName_")
+ source.Append(" if (info.TryGetProperty(PropertyName.")
.Append(fieldName)
.Append(", out var _value_")
.Append(fieldName)
@@ -245,7 +245,7 @@ namespace Godot.SourceGenerators
source.Append(" if (info.TryGetSignalEventDelegate<")
.Append(signalDelegateQualifiedName)
- .Append(">(GodotInternal.SignalName_")
+ .Append(">(SignalName.")
.Append(signalName)
.Append(", out var _value_")
.Append(signalName)
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
index 6b06f10db1..1df41a905b 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -173,14 +173,16 @@ namespace Godot.SourceGenerators
godotSignalDelegates.Add(new(signalName, signalDelegateSymbol, invokeMethodData.Value));
}
- source.Append(" private partial class GodotInternal {\n");
+ source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
+
+ source.Append($" public new class SignalName : {symbol.BaseType.FullQualifiedName()}.SignalName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
foreach (var signalDelegate in godotSignalDelegates)
{
string signalName = signalDelegate.Name;
- source.Append(" public static readonly StringName SignalName_");
+ source.Append(" public new static readonly StringName ");
source.Append(signalName);
source.Append(" = \"");
source.Append(signalName);
@@ -193,8 +195,6 @@ namespace Godot.SourceGenerators
if (godotSignalDelegates.Count > 0)
{
- source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
-
const string listType = "System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
source.Append(" internal new static ")
@@ -215,10 +215,10 @@ namespace Godot.SourceGenerators
source.Append(" return signals;\n");
source.Append(" }\n");
-
- source.Append("#pragma warning restore CS0109\n");
}
+ source.Append("#pragma warning restore CS0109\n");
+
// Generate signal event
foreach (var signalDelegate in godotSignalDelegates)
@@ -291,7 +291,7 @@ namespace Godot.SourceGenerators
private static void AppendMethodInfo(StringBuilder source, MethodInfo methodInfo)
{
- source.Append(" signals.Add(new(name: GodotInternal.SignalName_")
+ source.Append(" signals.Add(new(name: SignalName.")
.Append(methodInfo.Name)
.Append(", returnVal: ");
@@ -400,7 +400,7 @@ namespace Godot.SourceGenerators
string signalName = signal.Name;
var invokeMethodData = signal.InvokeMethodData;
- source.Append(" if (signal == GodotInternal.SignalName_");
+ source.Append(" if (signal == SignalName.");
source.Append(signalName);
source.Append(" && argCount == ");
source.Append(invokeMethodData.ParamTypes.Length);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index 180cc3cf14..ad4fce8daa 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -117,13 +117,13 @@ namespace GodotTools.Build
}
}
- private void IssueActivated(int idx)
+ private void IssueActivated(long idx)
{
if (idx < 0 || idx >= _issuesList.ItemCount)
throw new ArgumentOutOfRangeException(nameof(idx), "Item list index out of range.");
// Get correct issue idx from issue list
- int issueIndex = (int)_issuesList.GetItemMetadata(idx);
+ int issueIndex = (int)_issuesList.GetItemMetadata((int)idx);
if (issueIndex < 0 || issueIndex >= _issues.Count)
throw new InvalidOperationException("Issue index out of range.");
@@ -311,7 +311,7 @@ namespace GodotTools.Build
Copy
}
- private void IssuesListContextOptionPressed(int id)
+ private void IssuesListContextOptionPressed(long id)
{
switch ((IssuesContextMenuOption)id)
{
@@ -336,9 +336,9 @@ namespace GodotTools.Build
}
}
- private void IssuesListClicked(int index, Vector2 atPosition, int mouseButtonIndex)
+ private void IssuesListClicked(long index, Vector2 atPosition, long mouseButtonIndex)
{
- if (mouseButtonIndex != (int)MouseButton.Right)
+ if (mouseButtonIndex != (long)MouseButton.Right)
{
return;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index 655be0ab5e..d0cd529d1f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -176,8 +176,9 @@ namespace GodotTools.Build
arguments.Add("--no-restore");
// Incremental or rebuild
- if (buildInfo.Rebuild)
- arguments.Add("--no-incremental");
+ // TODO: Not supported in `dotnet publish` (https://github.com/dotnet/sdk/issues/11099)
+ // if (buildInfo.Rebuild)
+ // arguments.Add("--no-incremental");
// Configuration
arguments.Add("-c");
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs
index 7bce53308c..b437c7e742 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
+using System.Runtime.InteropServices;
using JetBrains.Annotations;
using OS = GodotTools.Utils.OS;
@@ -16,6 +17,23 @@ namespace GodotTools.Build
// In the future, this method may do more than just search in PATH. We could look in
// known locations or use Godot's linked nethost to search from the hostfxr location.
+ if (OS.IsMacOS)
+ {
+ if (RuntimeInformation.OSArchitecture == Architecture.X64)
+ {
+ string dotnet_x64 = "/usr/local/share/dotnet/x64/dotnet"; // Look for x64 version, when running under Rosetta 2.
+ if (File.Exists(dotnet_x64))
+ {
+ return dotnet_x64;
+ }
+ }
+ string dotnet = "/usr/local/share/dotnet/dotnet"; // Look for native version.
+ if (File.Exists(dotnet))
+ {
+ return dotnet;
+ }
+ }
+
return OS.PathWhich("dotnet");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
index d05995c495..237ac85267 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs
@@ -93,7 +93,7 @@ namespace GodotTools.Build
private void ViewLogToggled(bool pressed) => BuildOutputView.LogVisible = pressed;
- private void BuildMenuOptionPressed(int id)
+ private void BuildMenuOptionPressed(long id)
{
switch ((BuildMenuOptions)id)
{
@@ -122,7 +122,7 @@ namespace GodotTools.Build
{
base._Ready();
- CustomMinimumSize = new Vector2(0, 228) * EditorScale;
+ CustomMinimumSize = new Vector2i(0, (int)(228 * EditorScale));
SizeFlagsVertical = (int)SizeFlags.ExpandFill;
var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill };
@@ -175,7 +175,7 @@ namespace GodotTools.Build
AddChild(BuildOutputView);
}
- public override void _Notification(int what)
+ public override void _Notification(long what)
{
base._Notification(what);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index 951bff7e7a..0d2bea2363 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -67,7 +67,7 @@ namespace GodotTools.Export
}
}
- public override void _ExportBegin(string[] features, bool isDebug, string path, int flags)
+ public override void _ExportBegin(string[] features, bool isDebug, string path, long flags)
{
base._ExportBegin(features, isDebug, path, flags);
@@ -90,7 +90,7 @@ namespace GodotTools.Export
}
}
- private void _ExportBeginImpl(string[] features, bool isDebug, string path, int flags)
+ private void _ExportBeginImpl(string[] features, bool isDebug, string path, long flags)
{
_ = flags; // Unused
@@ -112,7 +112,7 @@ namespace GodotTools.Export
string buildConfig = isDebug ? "ExportDebug" : "ExportRelease";
// TODO: This works for now, as we only implemented support for x86 family desktop so far, but it needs to be fixed
- string arch = features.Contains("64") ? "x86_64" : "x86";
+ string arch = features.Contains("x86_64") ? "x86_64" : "x86";
string ridOS = DetermineRuntimeIdentifierOS(platform);
string ridArch = DetermineRuntimeIdentifierArch(arch);
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 994c11fa72..1cfaea3ec9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -111,7 +111,7 @@ namespace GodotTools
_toolBarBuildButton.Show();
}
- private void _MenuOptionPressed(int id)
+ private void _MenuOptionPressed(long id)
{
switch ((MenuOptions)id)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
index 260d13a714..89ac8058b9 100644
--- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs
@@ -9,7 +9,7 @@ namespace GodotTools
{
private Timer _watchTimer;
- public override void _Notification(int what)
+ public override void _Notification(long what)
{
if (what == Node.NotificationWmWindowFocusIn)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 6290b2c56f..c16f803226 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -70,9 +70,7 @@ namespace GodotTools.Utils
{
["Windows"] = Platforms.Windows,
["macOS"] = Platforms.MacOS,
- ["LinuxBSD"] = Platforms.LinuxBSD,
- // "X11" for compatibility, temporarily, while we are on an outdated branch
- ["X11"] = Platforms.LinuxBSD,
+ ["Linux"] = Platforms.LinuxBSD,
["UWP"] = Platforms.UWP,
["Haiku"] = Platforms.Haiku,
["Android"] = Platforms.Android,
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index d70a1e6c88..c27bb959fe 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -113,7 +113,7 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) {
#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL ".ConvertSignalToManaged"
// Types that will be ignored by the generator and won't be available in C#.
-const Vector<String> ignored_types = { "PhysicsServer3DExtension" };
+const Vector<String> ignored_types = { "PhysicsServer2DExtension", "PhysicsServer3DExtension" };
void BindingsGenerator::TypeInterface::postsetup_enum_type(BindingsGenerator::TypeInterface &r_enum_itype) {
// C interface for enums is the same as that of 'uint32_t'. Remember to apply
@@ -1315,7 +1315,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// Generate GodotSharp source files
- String core_proj_dir = output_dir.plus_file(CORE_API_ASSEMBLY_NAME);
+ String core_proj_dir = output_dir.path_join(CORE_API_ASSEMBLY_NAME);
proj_err = generate_cs_core_project(core_proj_dir);
if (proj_err != OK) {
@@ -1325,7 +1325,7 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// Generate GodotSharpEditor source files
- String editor_proj_dir = output_dir.plus_file(EDITOR_API_ASSEMBLY_NAME);
+ String editor_proj_dir = output_dir.path_join(EDITOR_API_ASSEMBLY_NAME);
proj_err = generate_cs_editor_project(editor_proj_dir);
if (proj_err != OK) {
@@ -2585,6 +2585,16 @@ const String BindingsGenerator::_get_generic_type_parameters(const TypeInterface
return params;
}
+StringName BindingsGenerator::_get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta) {
+ if (p_type == Variant::INT) {
+ return _get_int_type_name_from_meta(p_meta);
+ } else if (p_type == Variant::FLOAT) {
+ return _get_float_type_name_from_meta(p_meta);
+ } else {
+ return Variant::get_type_name(p_type);
+ }
+}
+
StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta) {
switch (p_meta) {
case GodotTypeInfo::METADATA_INT_IS_INT8:
@@ -2612,8 +2622,8 @@ StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metada
return "ulong";
break;
default:
- // Assume INT32
- return "int";
+ // Assume INT64
+ return "long";
}
}
@@ -2626,12 +2636,8 @@ StringName BindingsGenerator::_get_float_type_name_from_meta(GodotTypeInfo::Meta
return "double";
break;
default:
- // Assume real_t (float or double depending of REAL_T_IS_DOUBLE)
-#ifdef REAL_T_IS_DOUBLE
+ // Assume FLOAT64
return "double";
-#else
- return "float";
-#endif
}
}
@@ -2922,13 +2928,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else if (return_info.type == Variant::NIL) {
imethod.return_type.cname = name_cache.type_void;
} else {
- if (return_info.type == Variant::INT) {
- imethod.return_type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE);
- } else if (return_info.type == Variant::FLOAT) {
- imethod.return_type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE);
- } else {
- imethod.return_type.cname = Variant::get_type_name(return_info.type);
- }
+ imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE);
}
for (int i = 0; i < argc; i++) {
@@ -2952,13 +2952,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else if (arginfo.type == Variant::NIL) {
iarg.type.cname = name_cache.type_Variant;
} else {
- if (arginfo.type == Variant::INT) {
- iarg.type.cname = _get_int_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE);
- } else if (arginfo.type == Variant::FLOAT) {
- iarg.type.cname = _get_float_type_name_from_meta(m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE);
- } else {
- iarg.type.cname = Variant::get_type_name(arginfo.type);
- }
+ iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE);
}
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
@@ -3060,13 +3054,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
} else if (arginfo.type == Variant::NIL) {
iarg.type.cname = name_cache.type_Variant;
} else {
- if (arginfo.type == Variant::INT) {
- iarg.type.cname = _get_int_type_name_from_meta(GodotTypeInfo::METADATA_NONE);
- } else if (arginfo.type == Variant::FLOAT) {
- iarg.type.cname = _get_float_type_name_from_meta(GodotTypeInfo::METADATA_NONE);
- } else {
- iarg.type.cname = Variant::get_type_name(arginfo.type);
- }
+ iarg.type.cname = _get_type_name_from_meta(arginfo.type, GodotTypeInfo::METADATA_NONE);
}
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
@@ -3880,7 +3868,7 @@ static void handle_cmdline_options(String glue_dir_path) {
CRASH_COND(glue_dir_path.is_empty());
- if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) {
+ if (bindings_generator.generate_cs_api(glue_dir_path.path_join(API_SOLUTION_NAME)) != OK) {
ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API.");
}
}
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index c1295385dc..a479c44368 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -703,6 +703,7 @@ class BindingsGenerator {
const String _get_generic_type_parameters(const TypeInterface &p_itype, const List<TypeReference> &p_generic_type_parameters);
+ StringName _get_type_name_from_meta(Variant::Type p_type, GodotTypeInfo::Metadata p_meta);
StringName _get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 36c46627e2..40296eef10 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -163,9 +163,9 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
}
if (dir_access->dir_exists(filename)) {
- directories.push_back(dir_access->get_current_dir().plus_file(filename));
+ directories.push_back(dir_access->get_current_dir().path_join(filename));
} else if (filename.ends_with(".tscn") || filename.ends_with(".scn")) {
- suggestions.push_back(quoted(dir_access->get_current_dir().plus_file(filename)));
+ suggestions.push_back(quoted(dir_access->get_current_dir().path_join(filename)));
}
filename = dir_access->get_next();
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 1ef78c3ac2..6f42ad6916 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -98,7 +98,7 @@ bool godot_icall_EditorProgress_Step(const godot_string *p_task, const godot_str
}
void godot_icall_Internal_FullExportTemplatesDir(godot_string *r_dest) {
- String full_templates_dir = EditorPaths::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG);
+ String full_templates_dir = EditorPaths::get_singleton()->get_export_templates_dir().path_join(VERSION_FULL_CONFIG);
memnew_placement(r_dest, String(full_templates_dir));
}
diff --git a/modules/mono/editor/hostfxr_resolver.cpp b/modules/mono/editor/hostfxr_resolver.cpp
new file mode 100644
index 0000000000..ea5978b2cd
--- /dev/null
+++ b/modules/mono/editor/hostfxr_resolver.cpp
@@ -0,0 +1,335 @@
+/*************************************************************************/
+/* hostfxr_resolver.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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. */
+/*************************************************************************/
+
+/*
+Adapted to Godot from the nethost library: https://github.com/dotnet/runtime/tree/main/src/native/corehost
+*/
+
+/*
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+*/
+
+#include "hostfxr_resolver.h"
+
+#include "core/config/engine.h"
+#include "core/io/dir_access.h"
+#include "core/io/file_access.h"
+#include "core/os/os.h"
+
+#ifdef WINDOWS_ENABLED
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "../utils/path_utils.h"
+#include "semver.h"
+
+// We don't use libnethost as it gives us issues with some compilers.
+// This file tries to mimic libnethost's hostfxr_resolver search logic. We try to use the
+// same function names for easier comparing in case we need to update this in the future.
+
+namespace {
+
+String get_hostfxr_file_name() {
+#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
+ return "hostfxr.dll";
+#elif defined(MACOS_ENABLED) || defined(IOS_ENABLED)
+ return "libhostfxr.dylib";
+#else
+ return "libhostfxr.so";
+#endif
+}
+
+bool get_latest_fxr(const String &fxr_root, String &r_fxr_path) {
+ godotsharp::SemVerParser sem_ver_parser;
+
+ bool found_ver = false;
+ godotsharp::SemVer latest_ver;
+ String latest_ver_str;
+
+ Ref<DirAccess> da = DirAccess::open(fxr_root);
+ da->list_dir_begin();
+ for (String dir = da->get_next(); !dir.is_empty(); dir = da->get_next()) {
+ if (!da->current_is_dir() || dir == "." || dir == "..") {
+ continue;
+ }
+
+ String ver = dir.get_file();
+
+ godotsharp::SemVer fx_ver;
+ if (sem_ver_parser.parse(ver, fx_ver)) {
+ if (!found_ver || fx_ver > latest_ver) {
+ latest_ver = fx_ver;
+ latest_ver_str = ver;
+ found_ver = true;
+ }
+ }
+ }
+
+ if (!found_ver) {
+ return false;
+ }
+
+ String fxr_with_ver = path::join(fxr_root, latest_ver_str);
+ String hostfxr_file_path = path::join(fxr_with_ver, get_hostfxr_file_name());
+
+ ERR_FAIL_COND_V_MSG(!FileAccess::exists(hostfxr_file_path), false, "Missing hostfxr library in directory: " + fxr_with_ver);
+
+ r_fxr_path = hostfxr_file_path;
+
+ return true;
+}
+
+#ifdef WINDOWS_ENABLED
+typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
+
+BOOL is_wow64() {
+ BOOL wow64 = FALSE;
+
+ LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
+
+ if (fnIsWow64Process) {
+ if (!fnIsWow64Process(GetCurrentProcess(), &wow64)) {
+ wow64 = FALSE;
+ }
+ }
+
+ return wow64;
+}
+#endif
+
+static const char *arch_name_map[][2] = {
+ { "arm32", "arm" },
+ { "arm64", "arm64" },
+ { "rv64", "riscv64" },
+ { "x86_64", "x64" },
+ { "x86_32", "x86" },
+ { nullptr, nullptr }
+};
+
+String get_dotnet_arch() {
+ String arch = Engine::get_singleton()->get_architecture_name();
+
+ int idx = 0;
+ while (arch_name_map[idx][0] != nullptr) {
+ if (arch_name_map[idx][0] == arch) {
+ return arch_name_map[idx][1];
+ }
+ idx++;
+ }
+
+ return "";
+}
+
+bool get_default_installation_dir(String &r_dotnet_root) {
+#if defined(WINDOWS_ENABLED)
+ String program_files_env;
+ if (is_wow64()) {
+ // Running x86 on x64, looking for x86 install
+ program_files_env = "ProgramFiles(x86)";
+ } else {
+ program_files_env = "ProgramFiles";
+ }
+
+ String program_files_dir = OS::get_singleton()->get_environment(program_files_env);
+
+ if (program_files_dir.is_empty()) {
+ return false;
+ }
+
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
+ // When emulating x64 on arm
+ String dotnet_root_emulated = path::join(program_files_dir, "dotnet", "x64");
+ if (FileAccess::exists(path::join(dotnet_root_emulated, "dotnet.exe"))) {
+ r_dotnet_root = dotnet_root_emulated;
+ return true;
+ }
+#endif
+
+ r_dotnet_root = path::join(program_files_dir, "dotnet");
+ return true;
+#elif defined(MACOS_ENABLED)
+ r_dotnet_root = "/usr/local/share/dotnet";
+
+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
+ // When emulating x64 on arm
+ String dotnet_root_emulated = path::join(r_dotnet_root, "x64");
+ if (FileAccess::exists(path::join(dotnet_root_emulated, "dotnet"))) {
+ r_dotnet_root = dotnet_root_emulated;
+ return true;
+ }
+#endif
+
+ return true;
+#else
+ r_dotnet_root = "/usr/share/dotnet";
+ return true;
+#endif
+}
+
+bool get_install_location_from_file(const String &p_file_path, String &r_dotnet_root) {
+ Error err = OK;
+ Ref<FileAccess> f = FileAccess::open(p_file_path, FileAccess::READ, &err);
+
+ if (f.is_null() || err != OK) {
+ return false;
+ }
+
+ String line = f->get_line();
+
+ if (line.is_empty()) {
+ return false;
+ }
+
+ r_dotnet_root = line;
+ return true;
+}
+
+bool get_dotnet_self_registered_dir(String &r_dotnet_root) {
+#if defined(WINDOWS_ENABLED)
+ String sub_key = "SOFTWARE\\dotnet\\Setup\\InstalledVersions\\" + get_dotnet_arch();
+ Char16String value = String("InstallLocation").utf16();
+
+ HKEY hkey = NULL;
+ LSTATUS result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)(sub_key.utf16().get_data()), 0, KEY_READ | KEY_WOW64_32KEY, &hkey);
+ if (result != ERROR_SUCCESS) {
+ return false;
+ }
+
+ DWORD size = 0;
+ result = RegGetValueW(hkey, nullptr, (LPCWSTR)(value.get_data()), RRF_RT_REG_SZ, nullptr, nullptr, &size);
+ if (result != ERROR_SUCCESS || size == 0) {
+ RegCloseKey(hkey);
+ return false;
+ }
+
+ Vector<WCHAR> buffer;
+ buffer.resize(size / sizeof(WCHAR));
+ result = RegGetValueW(hkey, nullptr, (LPCWSTR)(value.get_data()), RRF_RT_REG_SZ, nullptr, (LPBYTE)buffer.ptrw(), &size);
+ if (result != ERROR_SUCCESS) {
+ RegCloseKey(hkey);
+ return false;
+ }
+
+ r_dotnet_root = String::utf16((const char16_t *)buffer.ptr());
+ RegCloseKey(hkey);
+ return true;
+#else
+ String install_location_file = path::join("/etc/dotnet", "install_location_" + get_dotnet_arch().to_lower());
+ if (get_install_location_from_file(install_location_file, r_dotnet_root)) {
+ return true;
+ }
+
+ if (FileAccess::exists(install_location_file)) {
+ // Don't try with the legacy location, this will fall back to the hard-coded default install location
+ return false;
+ }
+
+ String legacy_install_location_file = path::join("/etc/dotnet", "install_location");
+ return get_install_location_from_file(legacy_install_location_file, r_dotnet_root);
+#endif
+}
+
+bool get_file_path_from_env(const String &p_env_key, String &r_dotnet_root) {
+ String env_value = OS::get_singleton()->get_environment(p_env_key);
+
+ if (!env_value.is_empty()) {
+ env_value = path::realpath(env_value);
+
+ if (DirAccess::exists(env_value)) {
+ r_dotnet_root = env_value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool get_dotnet_root_from_env(String &r_dotnet_root) {
+ String dotnet_root_env = "DOTNET_ROOT";
+ String arch_for_env = get_dotnet_arch();
+
+ if (!arch_for_env.is_empty()) {
+ // DOTNET_ROOT_<arch>
+ if (get_file_path_from_env(dotnet_root_env + "_" + arch_for_env.to_upper(), r_dotnet_root)) {
+ return true;
+ }
+ }
+
+#ifdef WINDOWS_ENABLED
+ // WoW64-only: DOTNET_ROOT(x86)
+ if (is_wow64() && get_file_path_from_env("DOTNET_ROOT(x86)", r_dotnet_root)) {
+ return true;
+ }
+#endif
+
+ // DOTNET_ROOT
+ return get_file_path_from_env(dotnet_root_env, r_dotnet_root);
+}
+
+} //namespace
+
+bool godotsharp::hostfxr_resolver::try_get_path_from_dotnet_root(const String &p_dotnet_root, String &r_fxr_path) {
+ String fxr_dir = path::join(p_dotnet_root, "host", "fxr");
+ ERR_FAIL_COND_V_MSG(!DirAccess::exists(fxr_dir), false, "The host fxr folder does not exist: " + fxr_dir);
+ return get_latest_fxr(fxr_dir, r_fxr_path);
+}
+
+bool godotsharp::hostfxr_resolver::try_get_path(String &r_dotnet_root, String &r_fxr_path) {
+ if (!get_dotnet_root_from_env(r_dotnet_root) &&
+ !get_dotnet_self_registered_dir(r_dotnet_root) &&
+ !get_default_installation_dir(r_dotnet_root)) {
+ return false;
+ }
+
+ return try_get_path_from_dotnet_root(r_dotnet_root, r_fxr_path);
+}
diff --git a/modules/mono/editor/hostfxr_resolver.h b/modules/mono/editor/hostfxr_resolver.h
new file mode 100644
index 0000000000..0f029ab7ae
--- /dev/null
+++ b/modules/mono/editor/hostfxr_resolver.h
@@ -0,0 +1,45 @@
+/*************************************************************************/
+/* hostfxr_resolver.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 HOSTFXR_RESOLVER_H
+#define HOSTFXR_RESOLVER_H
+
+#include "core/string/ustring.h"
+
+namespace godotsharp {
+namespace hostfxr_resolver {
+
+bool try_get_path_from_dotnet_root(const String &p_dotnet_root, String &r_out_fxr_path);
+bool try_get_path(String &r_out_dotnet_root, String &r_out_fxr_path);
+
+} //namespace hostfxr_resolver
+} //namespace godotsharp
+
+#endif // HOSTFXR_RESOLVER_H
diff --git a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
index 1f5ea7532d..fbad482cf6 100644
--- a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
+++ b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
@@ -11,13 +11,13 @@ public partial class _CLASS_ : _BASE_
// Get the gravity from the project settings to be synced with RigidBody nodes.
public float gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
- public override void _PhysicsProcess(float delta)
+ public override void _PhysicsProcess(double delta)
{
Vector2 velocity = Velocity;
// Add the gravity.
if (!IsOnFloor())
- velocity.y += gravity * delta;
+ velocity.y += gravity * (float)delta;
// Handle Jump.
if (Input.IsActionJustPressed("ui_accept") && IsOnFloor())
diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
index 4e978b7549..abed246a1e 100644
--- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
+++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
@@ -11,17 +11,17 @@ public partial class _CLASS_ : _BASE_
// Get the gravity from the project settings to be synced with RigidBody nodes.
public float gravity = ProjectSettings.GetSetting("physics/3d/default_gravity").AsSingle();
- public override void _PhysicsProcess(float delta)
+ public override void _PhysicsProcess(double delta)
{
Vector3 velocity = Velocity;
// Add the gravity.
if (!IsOnFloor())
- velocity.y -= gravity * delta;
+ velocity.y -= gravity * (float)delta;
// Handle Jump.
if (Input.IsActionJustPressed("ui_accept") && IsOnFloor())
- velocity.y = JumpVelocity;
+ velocity.y = JumpVelocity;
// Get the input direction and handle the movement/deceleration.
// As good practice, you should replace UI actions with custom gameplay actions.
diff --git a/modules/mono/editor/script_templates/Node/default.cs b/modules/mono/editor/script_templates/Node/default.cs
index 4c86d1666f..74ece028fc 100644
--- a/modules/mono/editor/script_templates/Node/default.cs
+++ b/modules/mono/editor/script_templates/Node/default.cs
@@ -11,7 +11,7 @@ public partial class _CLASS_ : _BASE_
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
}
}
diff --git a/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs b/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs
index bb482e0d6a..cd335934db 100644
--- a/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs
+++ b/modules/mono/editor/script_templates/VisualShaderNodeCustom/basic.cs
@@ -20,37 +20,37 @@ public partial class VisualShaderNode_CLASS_ : _BASE_
return "";
}
- public override int _GetReturnIconType()
+ public override long _GetReturnIconType()
{
return 0;
}
- public override int _GetInputPortCount()
+ public override long _GetInputPortCount()
{
return 0;
}
- public override string _GetInputPortName(int port)
+ public override string _GetInputPortName(long port)
{
return "";
}
- public override int _GetInputPortType(int port)
+ public override long _GetInputPortType(long port)
{
return 0;
}
- public override int _GetOutputPortCount()
+ public override long _GetOutputPortCount()
{
return 1;
}
- public override string _GetOutputPortName(int port)
+ public override string _GetOutputPortName(long port)
{
return "result";
}
- public override int _GetOutputPortType(int port)
+ public override long _GetOutputPortType(long port)
{
return 0;
}
diff --git a/modules/mono/editor/semver.cpp b/modules/mono/editor/semver.cpp
new file mode 100644
index 0000000000..1656d0932f
--- /dev/null
+++ b/modules/mono/editor/semver.cpp
@@ -0,0 +1,149 @@
+/*************************************************************************/
+/* semver.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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. */
+/*************************************************************************/
+
+#include "semver.h"
+
+bool godotsharp::SemVer::parse_digit_only_field(const String &p_field, uint64_t &r_result) {
+ if (p_field.is_empty()) {
+ return false;
+ }
+
+ int64_t integer = 0;
+
+ for (int i = 0; i < p_field.length(); i++) {
+ char32_t c = p_field[i];
+ if (is_digit(c)) {
+ bool overflow = ((uint64_t)integer > UINT64_MAX / 10) || ((uint64_t)integer == UINT64_MAX / 10 && c > '5');
+ ERR_FAIL_COND_V_MSG(overflow, false, "Cannot represent '" + p_field + "' as a 64-bit unsigned integer, since the value is too large.");
+ integer *= 10;
+ integer += c - '0';
+ } else {
+ return false;
+ }
+ }
+
+ r_result = (uint64_t)integer;
+ return true;
+}
+
+int godotsharp::SemVer::cmp(const godotsharp::SemVer &p_a, const godotsharp::SemVer &p_b) {
+ if (p_a.major != p_b.major) {
+ return p_a.major > p_b.major ? 1 : -1;
+ }
+
+ if (p_a.minor != p_b.minor) {
+ return p_a.minor > p_b.minor ? 1 : -1;
+ }
+
+ if (p_a.patch != p_b.patch) {
+ return p_a.patch > p_b.patch ? 1 : -1;
+ }
+
+ if (p_a.prerelease.is_empty() && p_b.prerelease.is_empty()) {
+ return 0;
+ }
+
+ if (p_a.prerelease.is_empty() || p_b.prerelease.is_empty()) {
+ return p_a.prerelease.is_empty() ? 1 : -1;
+ }
+
+ if (p_a.prerelease != p_b.prerelease) {
+ // This could be optimized, but I'm too lazy
+
+ Vector<String> a_field_set = p_a.prerelease.split(".");
+ Vector<String> b_field_set = p_b.prerelease.split(".");
+
+ int a_field_count = a_field_set.size();
+ int b_field_count = b_field_set.size();
+
+ int min_field_count = MIN(a_field_count, b_field_count);
+
+ for (int i = 0; i < min_field_count; i++) {
+ const String &a_field = a_field_set[i];
+ const String &b_field = b_field_set[i];
+
+ if (a_field == b_field) {
+ continue;
+ }
+
+ uint64_t a_num;
+ bool a_is_digit_only = parse_digit_only_field(a_field, a_num);
+
+ uint64_t b_num;
+ bool b_is_digit_only = parse_digit_only_field(b_field, b_num);
+
+ if (a_is_digit_only && b_is_digit_only) {
+ // Identifiers consisting of only digits are compared numerically.
+
+ if (a_num == b_num) {
+ continue;
+ }
+
+ return a_num > b_num ? 1 : -1;
+ }
+
+ if (a_is_digit_only || b_is_digit_only) {
+ // Numeric identifiers always have lower precedence than non-numeric identifiers.
+ return b_is_digit_only ? 1 : -1;
+ }
+
+ // Identifiers with letters or hyphens are compared lexically in ASCII sort order.
+ return a_field > b_field ? 1 : -1;
+ }
+
+ if (a_field_count != b_field_count) {
+ // A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal.
+ return a_field_count > b_field_count ? 1 : -1;
+ }
+ }
+
+ return 0;
+}
+
+bool godotsharp::SemVerParser::parse(const String &p_ver_text, godotsharp::SemVer &r_semver) {
+ if (!regex.is_valid() && regex.get_pattern().is_empty()) {
+ regex.compile("^(?P<major>0|[1-9]\\d*)\\.(?P<minor>0|[1-9]\\d*)\\.(?P<patch>0|[1-9]\\d*)(?:-(?P<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
+ ERR_FAIL_COND_V(!regex.is_valid(), false);
+ }
+
+ Ref<RegExMatch> match = regex.search(p_ver_text);
+
+ if (match.is_valid()) {
+ r_semver = SemVer(
+ match->get_string("major").to_int(),
+ match->get_string("minor").to_int(),
+ match->get_string("patch").to_int(),
+ match->get_string("prerelease"),
+ match->get_string("buildmetadata"));
+ return true;
+ }
+
+ return false;
+}
diff --git a/modules/mono/editor/semver.h b/modules/mono/editor/semver.h
new file mode 100644
index 0000000000..48ea8b043e
--- /dev/null
+++ b/modules/mono/editor/semver.h
@@ -0,0 +1,106 @@
+/*************************************************************************/
+/* semver.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 SEMVER_H
+#define SEMVER_H
+
+#include "core/string/ustring.h"
+#include "modules/regex/regex.h"
+
+// <sys/sysmacros.h> is included somewhere, which defines major(dev) to gnu_dev_major(dev)
+#if defined(major)
+#undef major
+#endif
+#if defined(minor)
+#undef minor
+#endif
+
+namespace godotsharp {
+
+struct SemVer {
+private:
+ static bool parse_digit_only_field(const String &p_field, uint64_t &r_result);
+
+ static int cmp(const SemVer &p_a, const SemVer &p_b);
+
+public:
+ int major = 0;
+ int minor = 0;
+ int patch = 0;
+ String prerelease;
+ String build_metadata;
+
+ bool operator==(const SemVer &b) const {
+ return cmp(*this, b) == 0;
+ }
+
+ bool operator!=(const SemVer &b) const {
+ return !operator==(b);
+ }
+
+ bool operator<(const SemVer &b) const {
+ return cmp(*this, b) < 0;
+ }
+
+ bool operator>(const SemVer &b) const {
+ return cmp(*this, b) > 0;
+ }
+
+ bool operator<=(const SemVer &b) const {
+ return cmp(*this, b) <= 0;
+ }
+
+ bool operator>=(const SemVer &b) const {
+ return cmp(*this, b) >= 0;
+ }
+
+ SemVer() {}
+
+ SemVer(int p_major, int p_minor, int p_patch,
+ const String &p_prerelease, const String &p_build_metadata) :
+ major(p_major),
+ minor(p_minor),
+ patch(p_patch),
+ prerelease(p_prerelease),
+ build_metadata(p_build_metadata) {
+ }
+};
+
+struct SemVerParser {
+private:
+ RegEx regex;
+
+public:
+ bool parse(const String &p_ver_text, SemVer &r_semver);
+};
+
+} //namespace godotsharp
+
+#endif // SEMVER_H