summaryrefslogtreecommitdiff
path: root/modules/mono/editor/GodotSharpTools
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/editor/GodotSharpTools')
-rw-r--r--modules/mono/editor/GodotSharpTools/.gitignore2
-rw-r--r--modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs74
-rw-r--r--modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs105
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj8
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs14
-rw-r--r--modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs16
-rw-r--r--modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs41
-rw-r--r--modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs58
-rw-r--r--modules/mono/editor/GodotSharpTools/StringExtensions.cs4
-rw-r--r--modules/mono/editor/GodotSharpTools/Utils/OS.cs62
-rw-r--r--modules/mono/editor/GodotSharpTools/packages.config4
11 files changed, 339 insertions, 49 deletions
diff --git a/modules/mono/editor/GodotSharpTools/.gitignore b/modules/mono/editor/GodotSharpTools/.gitignore
new file mode 100644
index 0000000000..296ad48834
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/.gitignore
@@ -0,0 +1,2 @@
+# nuget packages
+packages \ No newline at end of file
diff --git a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
new file mode 100644
index 0000000000..5fd708d539
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+namespace GodotSharpTools.Editor
+{
+ public static class GodotSharpExport
+ {
+ public static void _ExportBegin(string[] features, bool debug, string path, int flags)
+ {
+ var featureSet = new HashSet<string>(features);
+
+ if (PlatformHasTemplateDir(featureSet))
+ {
+ string templateDirName = "data.mono";
+
+ if (featureSet.Contains("Windows"))
+ {
+ templateDirName += ".windows";
+ templateDirName += featureSet.Contains("64") ? ".64" : ".32";
+ }
+ else if (featureSet.Contains("X11"))
+ {
+ templateDirName += ".x11";
+ templateDirName += featureSet.Contains("64") ? ".64" : ".32";
+ }
+ else
+ {
+ throw new NotSupportedException("Target platform not supported");
+ }
+
+ templateDirName += debug ? ".debug" : ".release";
+
+ string templateDirPath = Path.Combine(GetTemplatesDir(), templateDirName);
+
+ if (!Directory.Exists(templateDirPath))
+ throw new FileNotFoundException("Data template directory not found");
+
+ string outputDir = new FileInfo(path).Directory.FullName;
+
+ string outputDataDir = Path.Combine(outputDir, GetDataDirName());
+
+ if (Directory.Exists(outputDataDir))
+ Directory.Delete(outputDataDir, recursive: true); // Clean first
+
+ Directory.CreateDirectory(outputDataDir);
+
+ foreach (string dir in Directory.GetDirectories(templateDirPath, "*", SearchOption.AllDirectories))
+ {
+ Directory.CreateDirectory(Path.Combine(outputDataDir, dir.Substring(templateDirPath.Length + 1)));
+ }
+
+ foreach (string file in Directory.GetFiles(templateDirPath, "*", SearchOption.AllDirectories))
+ {
+ File.Copy(file, Path.Combine(outputDataDir, file.Substring(templateDirPath.Length + 1)));
+ }
+ }
+ }
+
+ public static bool PlatformHasTemplateDir(HashSet<string> featureSet)
+ {
+ // OSX export templates are contained in a zip, so we place
+ // our custom template inside it and let Godot do the rest.
+ return !featureSet.Contains("OSX");
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetTemplatesDir();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetDataDirName();
+ }
+}
diff --git a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs b/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
index 303be3b732..fba4a8f65c 100644
--- a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
+++ b/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs
@@ -2,13 +2,23 @@ using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
namespace GodotSharpTools.Editor
{
public class MonoDevelopInstance
{
- private Process process;
- private string solutionFile;
+ public enum EditorId
+ {
+ MonoDevelop = 0,
+ VisualStudioForMac = 1
+ }
+
+ readonly string solutionFile;
+ readonly EditorId editorId;
+
+ Process process;
public void Execute(string[] files)
{
@@ -16,6 +26,35 @@ namespace GodotSharpTools.Editor
List<string> args = new List<string>();
+ string command;
+
+ if (Utils.OS.IsOSX())
+ {
+ string bundleId = codeEditorBundleIds[editorId];
+
+ if (IsApplicationBundleInstalled(bundleId))
+ {
+ command = "open";
+
+ args.Add("-b");
+ args.Add(bundleId);
+
+ // The 'open' process must wait until the application finishes
+ if (newWindow)
+ args.Add("--wait-apps");
+
+ args.Add("--args");
+ }
+ else
+ {
+ command = codeEditorPaths[editorId];
+ }
+ }
+ else
+ {
+ command = codeEditorPaths[editorId];
+ }
+
args.Add("--ipc-tcp");
if (newWindow)
@@ -33,25 +72,73 @@ namespace GodotSharpTools.Editor
if (newWindow)
{
- ProcessStartInfo startInfo = new ProcessStartInfo(MonoDevelopFile, string.Join(" ", args));
- process = Process.Start(startInfo);
+ process = Process.Start(new ProcessStartInfo()
+ {
+ FileName = command,
+ Arguments = string.Join(" ", args),
+ UseShellExecute = false
+ });
}
else
{
- Process.Start(MonoDevelopFile, string.Join(" ", args));
+ Process.Start(new ProcessStartInfo()
+ {
+ FileName = command,
+ Arguments = string.Join(" ", args),
+ UseShellExecute = false
+ });
}
}
- public MonoDevelopInstance(string solutionFile)
+ public MonoDevelopInstance(string solutionFile, EditorId editorId)
{
+ if (editorId == EditorId.VisualStudioForMac && !Utils.OS.IsOSX())
+ throw new InvalidOperationException($"{nameof(EditorId.VisualStudioForMac)} not supported on this platform");
+
this.solutionFile = solutionFile;
+ this.editorId = editorId;
}
- private static string MonoDevelopFile
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern static bool IsApplicationBundleInstalled(string bundleId);
+
+ static readonly IReadOnlyDictionary<EditorId, string> codeEditorPaths;
+ static readonly IReadOnlyDictionary<EditorId, string> codeEditorBundleIds;
+
+ static MonoDevelopInstance()
{
- get
+ if (Utils.OS.IsOSX())
+ {
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // Rely on PATH
+ { EditorId.MonoDevelop, "monodevelop" },
+ { EditorId.VisualStudioForMac, "VisualStudio" }
+ };
+ codeEditorBundleIds = new Dictionary<EditorId, string>
+ {
+ // TODO EditorId.MonoDevelop
+ { EditorId.VisualStudioForMac, "com.microsoft.visual-studio" }
+ };
+ }
+ else if (Utils.OS.IsWindows())
+ {
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // XamarinStudio is no longer a thing, and the latest version is quite old
+ // MonoDevelop is available from source only on Windows. The recommendation
+ // is to use Visual Studio instead. Since there are no official builds, we
+ // will rely on custom MonoDevelop builds being added to PATH.
+ { EditorId.MonoDevelop, "MonoDevelop.exe" }
+ };
+ }
+ else if (Utils.OS.IsUnix())
{
- return "monodevelop";
+ codeEditorPaths = new Dictionary<EditorId, string>
+ {
+ // Rely on PATH
+ { EditorId.MonoDevelop, "monodevelop" }
+ };
}
}
}
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
index 1c8714e31d..f9e9f41977 100644
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
+++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
@@ -31,6 +31,9 @@
<Reference Include="System" />
<Reference Include="Microsoft.Build" />
<Reference Include="Microsoft.Build.Framework" />
+ <Reference Include="DotNet.Glob, Version=2.1.1.0, Culture=neutral, PublicKeyToken=b68cc888b4f632d1, processorArchitecture=MSIL">
+ <HintPath>packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="StringExtensions.cs" />
@@ -40,6 +43,11 @@
<Compile Include="Project\ProjectGenerator.cs" />
<Compile Include="Project\ProjectUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Utils\OS.cs" />
+ <Compile Include="Editor\GodotSharpExport.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs b/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs
deleted file mode 100644
index 0cbafdc20d..0000000000
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.userprefs
+++ /dev/null
@@ -1,14 +0,0 @@
-<Properties StartupItem="GodotSharpTools.csproj">
- <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
- <MonoDevelop.Ide.Workbench ActiveDocument="Build/BuildSystem.cs">
- <Files>
- <File FileName="Build/ProjectExtensions.cs" Line="1" Column="1" />
- <File FileName="Build/ProjectGenerator.cs" Line="1" Column="1" />
- <File FileName="Build/BuildSystem.cs" Line="37" Column="14" />
- </Files>
- </MonoDevelop.Ide.Workbench>
- <MonoDevelop.Ide.DebuggingService.Breakpoints>
- <BreakpointStore />
- </MonoDevelop.Ide.DebuggingService.Breakpoints>
- <MonoDevelop.Ide.DebuggingService.PinnedWatches />
-</Properties> \ No newline at end of file
diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs
index f00ec5a2ad..647d9ac81d 100644
--- a/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs
+++ b/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using DotNet.Globbing;
using Microsoft.Build.Construction;
namespace GodotSharpTools.Project
@@ -7,7 +8,10 @@ namespace GodotSharpTools.Project
{
public static bool HasItem(this ProjectRootElement root, string itemType, string include)
{
- string includeNormalized = include.NormalizePath();
+ GlobOptions globOptions = new GlobOptions();
+ globOptions.Evaluation.CaseInsensitive = false;
+
+ string normalizedInclude = include.NormalizePath();
foreach (var itemGroup in root.ItemGroups)
{
@@ -16,10 +20,14 @@ namespace GodotSharpTools.Project
foreach (var item in itemGroup.Items)
{
- if (item.ItemType == itemType)
+ if (item.ItemType != itemType)
+ continue;
+
+ var glob = Glob.Parse(item.Include.NormalizePath(), globOptions);
+
+ if (glob.IsMatch(normalizedInclude))
{
- if (item.Include.NormalizePath() == includeNormalized)
- return true;
+ return true;
}
}
}
diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
index 1d863e6f61..2ce7837a27 100644
--- a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs
@@ -6,18 +6,24 @@ namespace GodotSharpTools.Project
{
public static class ProjectGenerator
{
+ public const string CoreApiProjectName = "GodotSharp";
+ public const string EditorApiProjectName = "GodotSharpEditor";
+ const string CoreApiProjectGuid = "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}";
+ const string EditorApiProjectGuid = "{8FBEC238-D944-4074-8548-B3B524305905}";
+
public static string GenCoreApiProject(string dir, string[] compileItems)
{
- string path = Path.Combine(dir, CoreApiProject + ".csproj");
+ string path = Path.Combine(dir, CoreApiProjectName + ".csproj");
ProjectPropertyGroupElement mainGroup;
- var root = CreateLibraryProject(CoreApiProject, out mainGroup);
+ var root = CreateLibraryProject(CoreApiProjectName, out mainGroup);
mainGroup.AddProperty("DocumentationFile", Path.Combine("$(OutputPath)", "$(AssemblyName).xml"));
mainGroup.SetProperty("RootNamespace", "Godot");
+ mainGroup.SetProperty("ProjectGuid", CoreApiProjectGuid);
- GenAssemblyInfoFile(root, dir, CoreApiProject,
- new string[] { "[assembly: InternalsVisibleTo(\"" + EditorApiProject + "\")]" },
+ GenAssemblyInfoFile(root, dir, CoreApiProjectName,
+ new string[] { "[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]" },
new string[] { "System.Runtime.CompilerServices" });
foreach (var item in compileItems)
@@ -27,33 +33,33 @@ namespace GodotSharpTools.Project
root.Save(path);
- return root.GetGuid().ToString().ToUpper();
+ return CoreApiProjectGuid;
}
- public static string GenEditorApiProject(string dir, string coreApiHintPath, string[] compileItems)
+ public static string GenEditorApiProject(string dir, string coreApiProjPath, string[] compileItems)
{
- string path = Path.Combine(dir, EditorApiProject + ".csproj");
+ string path = Path.Combine(dir, EditorApiProjectName + ".csproj");
ProjectPropertyGroupElement mainGroup;
- var root = CreateLibraryProject(EditorApiProject, out mainGroup);
+ var root = CreateLibraryProject(EditorApiProjectName, out mainGroup);
mainGroup.AddProperty("DocumentationFile", Path.Combine("$(OutputPath)", "$(AssemblyName).xml"));
mainGroup.SetProperty("RootNamespace", "Godot");
+ mainGroup.SetProperty("ProjectGuid", EditorApiProjectGuid);
- GenAssemblyInfoFile(root, dir, EditorApiProject);
+ GenAssemblyInfoFile(root, dir, EditorApiProjectName);
foreach (var item in compileItems)
{
root.AddItem("Compile", item.RelativeToPath(dir).Replace("/", "\\"));
}
- var coreApiRef = root.AddItem("Reference", CoreApiProject);
- coreApiRef.AddMetadata("HintPath", coreApiHintPath);
+ var coreApiRef = root.AddItem("ProjectReference", coreApiProjPath.Replace("/", "\\"));
coreApiRef.AddMetadata("Private", "False");
root.Save(path);
- return root.GetGuid().ToString().ToUpper();
+ return EditorApiProjectGuid;
}
public static string GenGameProject(string dir, string name, string[] compileItems)
@@ -77,13 +83,13 @@ namespace GodotSharpTools.Project
toolsGroup.AddProperty("WarningLevel", "4");
toolsGroup.AddProperty("ConsolePause", "false");
- var coreApiRef = root.AddItem("Reference", CoreApiProject);
- coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", CoreApiProject + ".dll"));
+ var coreApiRef = root.AddItem("Reference", CoreApiProjectName);
+ coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", CoreApiProjectName + ".dll"));
coreApiRef.AddMetadata("Private", "False");
- var editorApiRef = root.AddItem("Reference", EditorApiProject);
+ var editorApiRef = root.AddItem("Reference", EditorApiProjectName);
editorApiRef.Condition = " '$(Configuration)' == 'Tools' ";
- editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", EditorApiProject + ".dll"));
+ editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", EditorApiProjectName + ".dll"));
editorApiRef.AddMetadata("Private", "False");
GenAssemblyInfoFile(root, dir, name);
@@ -182,9 +188,6 @@ namespace GodotSharpTools.Project
}
}
- public const string CoreApiProject = "GodotSharp";
- public const string EditorApiProject = "GodotSharpEditor";
-
private const string assemblyInfoTemplate =
@"using System.Reflection;{0}
diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs
index 6889ea715f..a13f4fd6ef 100644
--- a/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs
+++ b/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs
@@ -1,5 +1,6 @@
-using System;
+using System.Collections.Generic;
using System.IO;
+using DotNet.Globbing;
using Microsoft.Build.Construction;
namespace GodotSharpTools.Project
@@ -10,8 +11,61 @@ namespace GodotSharpTools.Project
{
var dir = Directory.GetParent(projectPath).FullName;
var root = ProjectRootElement.Open(projectPath);
- if (root.AddItemChecked(itemType, include.RelativeToPath(dir).Replace("/", "\\")))
+ var normalizedInclude = include.RelativeToPath(dir).Replace("/", "\\");
+
+ if (root.AddItemChecked(itemType, normalizedInclude))
root.Save();
}
+
+ private static string[] GetAllFilesRecursive(string rootDirectory, string mask)
+ {
+ string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories);
+
+ // We want relative paths
+ for (int i = 0; i < files.Length; i++) {
+ files[i] = files[i].RelativeToPath(rootDirectory);
+ }
+
+ return files;
+ }
+
+ public static string[] GetIncludeFiles(string projectPath, string itemType)
+ {
+ var result = new List<string>();
+ var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
+
+ GlobOptions globOptions = new GlobOptions();
+ globOptions.Evaluation.CaseInsensitive = false;
+
+ var root = ProjectRootElement.Open(projectPath);
+
+ foreach (var itemGroup in root.ItemGroups)
+ {
+ if (itemGroup.Condition.Length != 0)
+ continue;
+
+ foreach (var item in itemGroup.Items)
+ {
+ if (item.ItemType != itemType)
+ continue;
+
+ string normalizedInclude = item.Include.NormalizePath();
+
+ var glob = Glob.Parse(normalizedInclude, globOptions);
+
+ // TODO Check somehow if path has no blog to avoid the following loop...
+
+ foreach (var existingFile in existingFiles)
+ {
+ if (glob.IsMatch(existingFile))
+ {
+ result.Add(existingFile);
+ }
+ }
+ }
+ }
+
+ return result.ToArray();
+ }
}
}
diff --git a/modules/mono/editor/GodotSharpTools/StringExtensions.cs b/modules/mono/editor/GodotSharpTools/StringExtensions.cs
index b66c86f8ce..b0436d2f18 100644
--- a/modules/mono/editor/GodotSharpTools/StringExtensions.cs
+++ b/modules/mono/editor/GodotSharpTools/StringExtensions.cs
@@ -36,7 +36,9 @@ namespace GodotSharpTools
public static bool IsAbsolutePath(this string path)
{
- return path.StartsWith("/") || path.StartsWith("\\") || path.StartsWith(driveRoot);
+ return path.StartsWith("/", StringComparison.Ordinal) ||
+ path.StartsWith("\\", StringComparison.Ordinal) ||
+ path.StartsWith(driveRoot, StringComparison.Ordinal);
}
public static string CsvEscape(this string value, char delimiter = ',')
diff --git a/modules/mono/editor/GodotSharpTools/Utils/OS.cs b/modules/mono/editor/GodotSharpTools/Utils/OS.cs
new file mode 100644
index 0000000000..148e954e77
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/Utils/OS.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace GodotSharpTools.Utils
+{
+ public static class OS
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetPlatformName();
+
+ const string HaikuName = "Haiku";
+ const string OSXName = "OSX";
+ const string ServerName = "Server";
+ const string UWPName = "UWP";
+ const string WindowsName = "Windows";
+ const string X11Name = "X11";
+
+ public static bool IsHaiku()
+ {
+ return HaikuName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsOSX()
+ {
+ return OSXName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsServer()
+ {
+ return ServerName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsUWP()
+ {
+ return UWPName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsWindows()
+ {
+ return WindowsName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ public static bool IsX11()
+ {
+ return X11Name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
+ }
+
+ static bool? IsUnixCache = null;
+ static readonly string[] UnixPlatforms = new string[] { HaikuName, OSXName, ServerName, X11Name };
+
+ public static bool IsUnix()
+ {
+ if (IsUnixCache.HasValue)
+ return IsUnixCache.Value;
+
+ string osName = GetPlatformName();
+ IsUnixCache = UnixPlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase));
+ return IsUnixCache.Value;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotSharpTools/packages.config b/modules/mono/editor/GodotSharpTools/packages.config
new file mode 100644
index 0000000000..2c7cb0bd4b
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="DotNet.Glob" version="2.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file