diff options
Diffstat (limited to 'modules/mono/editor')
14 files changed, 282 insertions, 294 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs index 7cf58b6755..4f21871f1a 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs @@ -91,13 +91,11 @@ namespace GodotTools.ProjectEditor var coreApiRef = root.AddItem("Reference", CoreApiProjectName); coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll")); - coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", CoreApiProjectName + ".dll")); coreApiRef.AddMetadata("Private", "False"); var editorApiRef = root.AddItem("Reference", EditorApiProjectName); editorApiRef.Condition = " '$(Configuration)' == 'Tools' "; editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll")); - editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", EditorApiProjectName + ".dll")); editorApiRef.AddMetadata("Private", "False"); GenAssemblyInfoFile(root, dir, name); diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs index 22cf89695d..1edc426e00 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -1,6 +1,8 @@ using GodotTools.Core; using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.Linq; using DotNet.Globbing; using Microsoft.Build.Construction; @@ -12,6 +14,8 @@ namespace GodotTools.ProjectEditor { var dir = Directory.GetParent(projectPath).FullName; var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + var normalizedInclude = include.RelativeToPath(dir).Replace("/", "\\"); if (root.AddItemChecked(itemType, normalizedInclude)) @@ -23,7 +27,8 @@ namespace GodotTools.ProjectEditor string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories); // We want relative paths - for (int i = 0; i < files.Length; i++) { + for (int i = 0; i < files.Length; i++) + { files[i] = files[i].RelativeToPath(rootDirectory); } @@ -35,7 +40,7 @@ namespace GodotTools.ProjectEditor var result = new List<string>(); var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); - GlobOptions globOptions = new GlobOptions(); + var globOptions = new GlobOptions(); globOptions.Evaluation.CaseInsensitive = false; var root = ProjectRootElement.Open(projectPath); @@ -68,5 +73,103 @@ namespace GodotTools.ProjectEditor return result.ToArray(); } + + /// Simple function to make sure the Api assembly references are configured correctly + public static void FixApiHintPath(string projectPath) + { + var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + + bool dirty = false; + + void AddPropertyIfNotPresent(string name, string condition, string value) + { + if (root.PropertyGroups + .Any(g => g.Condition == string.Empty || g.Condition == condition && + g.Properties + .Any(p => p.Name == name && + p.Value == value && + (p.Condition == condition || g.Condition == condition)))) + { + return; + } + + root.AddProperty(name, value).Condition = condition; + dirty = true; + } + + AddPropertyIfNotPresent(name: "ApiConfiguration", + condition: " '$(Configuration)' != 'Release' ", + value: "Debug"); + AddPropertyIfNotPresent(name: "ApiConfiguration", + condition: " '$(Configuration)' == 'Release' ", + value: "Release"); + + void SetReferenceHintPath(string referenceName, string condition, string hintPath) + { + foreach (var itemGroup in root.ItemGroups.Where(g => + g.Condition == string.Empty || g.Condition == condition)) + { + var references = itemGroup.Items.Where(item => + item.ItemType == "Reference" && + item.Include == referenceName && + (item.Condition == condition || itemGroup.Condition == condition)); + + var referencesWithHintPath = references.Where(reference => + reference.Metadata.Any(m => m.Name == "HintPath")); + + if (referencesWithHintPath.Any(reference => reference.Metadata + .Any(m => m.Name == "HintPath" && m.Value == hintPath))) + { + // Found a Reference item with the right HintPath + return; + } + + var referenceWithHintPath = referencesWithHintPath.FirstOrDefault(); + if (referenceWithHintPath != null) + { + // Found a Reference item with a wrong HintPath + foreach (var metadata in referenceWithHintPath.Metadata.ToList() + .Where(m => m.Name == "HintPath")) + { + // Safe to remove as we duplicate with ToList() to loop + referenceWithHintPath.RemoveChild(metadata); + } + + referenceWithHintPath.AddMetadata("HintPath", hintPath); + dirty = true; + return; + } + + var referenceWithoutHintPath = references.FirstOrDefault(); + if (referenceWithoutHintPath != null) + { + // Found a Reference item without a HintPath + referenceWithoutHintPath.AddMetadata("HintPath", hintPath); + dirty = true; + return; + } + } + + // Found no Reference item at all. Add it. + root.AddItem("Reference", referenceName).Condition = condition; + dirty = true; + } + + const string coreProjectName = "GodotSharp"; + const string editorProjectName = "GodotSharpEditor"; + + const string coreCondition = ""; + const string editorCondition = " '$(Configuration)' == 'Tools' "; + + var coreHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll"; + var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll"; + + SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath); + SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath); + + if (dirty) + root.Save(); + } } } diff --git a/modules/mono/editor/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln new file mode 100644 index 0000000000..6f7d44bec2 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.ProjectEditor", "GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj", "{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools", "GodotTools\GodotTools.csproj", "{27B00618-A6F2-4828-B922-05CAEB08C286}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Core", "GodotTools.Core\GodotTools.Core.csproj", "{639E48BD-44E5-4091-8EDD-22D36DC0768D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.BuildLogger", "GodotTools.BuildLogger\GodotTools.BuildLogger.csproj", "{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.Build.0 = Release|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Release|Any CPU.Build.0 = Release|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Release|Any CPU.Build.0 = Release|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs index a0d14c43c9..f0068385f4 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs @@ -172,7 +172,7 @@ namespace GodotTools.Build if (outputArray.Count == 0) return string.Empty; - var lines = outputArray[1].Split('\n'); + var lines = outputArray[0].Split('\n'); foreach (string line in lines) { diff --git a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs b/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs index 0426f0ac5a..4535ed7247 100644 --- a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs +++ b/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs @@ -1,9 +1,9 @@ using Godot; using System; -using System.Collections.Generic; using Godot.Collections; using GodotTools.Internals; using GodotTools.ProjectEditor; +using static GodotTools.Internals.Globals; using File = GodotTools.Utils.File; using Directory = GodotTools.Utils.Directory; @@ -11,11 +11,11 @@ namespace GodotTools { public static class CSharpProject { - public static string GenerateGameProject(string dir, string name, IEnumerable<string> files = null) + public static string GenerateGameProject(string dir, string name) { try { - return ProjectGenerator.GenGameProject(dir, name, files); + return ProjectGenerator.GenGameProject(dir, name, compileItems: new string[] { }); } catch (Exception e) { @@ -26,12 +26,24 @@ namespace GodotTools public static void AddItem(string projectPath, string itemType, string include) { - if (!(bool) Internal.GlobalDef("mono/project/auto_update_project", true)) + if (!(bool) GlobalDef("mono/project/auto_update_project", true)) return; ProjectUtils.AddItemToProjectChecked(projectPath, itemType, include); } + public static void FixApiHintPath(string projectPath) + { + try + { + ProjectUtils.FixApiHintPath(projectPath); + } + catch (Exception e) + { + GD.PushError(e.ToString()); + } + } + private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static ulong ConvertToTimestamp(this DateTime value) @@ -58,7 +70,7 @@ namespace GodotTools { var oldFileDict = (Dictionary) oldFileVar; - if (ulong.TryParse((string) oldFileDict["modified_time"], out ulong storedModifiedTime)) + if (ulong.TryParse(oldFileDict["modified_time"] as string, out ulong storedModifiedTime)) { if (storedModifiedTime == modifiedTime) { diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs index 433a931941..a884b0ead0 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using GodotTools.Build; using GodotTools.Internals; using GodotTools.Utils; +using static GodotTools.Internals.Globals; using Error = Godot.Error; using File = GodotTools.Utils.File; using Directory = GodotTools.Utils.Directory; @@ -192,134 +193,14 @@ namespace GodotTools return false; } - private static bool CopyApiAssembly(string srcDir, string dstDir, string assemblyName, ApiAssemblyType apiType) - { - // Create destination directory if needed - if (!Directory.Exists(dstDir)) - { - try - { - Directory.CreateDirectory(dstDir); - } - catch (IOException e) - { - ShowBuildErrorDialog($"Failed to create destination directory for the API assemblies. Exception message: {e.Message}"); - return false; - } - } - - string assemblyFile = assemblyName + ".dll"; - string assemblySrc = Path.Combine(srcDir, assemblyFile); - string assemblyDst = Path.Combine(dstDir, assemblyFile); - - if (!File.Exists(assemblyDst) || File.GetLastWriteTime(assemblySrc) > File.GetLastWriteTime(assemblyDst) || - Internal.MetadataIsApiAssemblyInvalidated(apiType)) - { - string xmlFile = $"{assemblyName}.xml"; - string pdbFile = $"{assemblyName}.pdb"; - - try - { - File.Copy(Path.Combine(srcDir, xmlFile), Path.Combine(dstDir, xmlFile)); - } - catch (IOException e) - { - Godot.GD.PushWarning(e.ToString()); - } - - try - { - File.Copy(Path.Combine(srcDir, pdbFile), Path.Combine(dstDir, pdbFile)); - } - catch (IOException e) - { - Godot.GD.PushWarning(e.ToString()); - } - - try - { - File.Copy(assemblySrc, assemblyDst); - } - catch (IOException e) - { - ShowBuildErrorDialog($"Failed to copy {assemblyFile}. Exception message: {e.Message}"); - return false; - } - - Internal.MetadataSetApiAssemblyInvalidated(apiType, false); - } - - return true; - } - - public static bool MakeApiAssembly(ApiAssemblyType apiType, string config) - { - string apiName = apiType == ApiAssemblyType.Core ? ApiAssemblyNames.Core : ApiAssemblyNames.Editor; - - string editorPrebuiltApiDir = Path.Combine(GodotSharpDirs.DataEditorPrebuiltApiDir, config); - string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, config); - - if (File.Exists(Path.Combine(editorPrebuiltApiDir, $"{apiName}.dll"))) - { - using (var copyProgress = new EditorProgress("mono_copy_prebuilt_api_assembly", $"Copying prebuilt {apiName} assembly...", 1)) - { - copyProgress.Step($"Copying {apiName} assembly", 0); - return CopyApiAssembly(editorPrebuiltApiDir, resAssembliesDir, apiName, apiType); - } - } - - const string apiSolutionName = ApiAssemblyNames.SolutionName; - - using (var pr = new EditorProgress($"mono_build_release_{apiSolutionName}", $"Building {apiSolutionName} solution...", 3)) - { - pr.Step($"Generating {apiSolutionName} solution", 0); - - string apiSlnDir = Path.Combine(GodotSharpDirs.MonoSolutionsDir, _ApiFolderName(ApiAssemblyType.Core)); - string apiSlnFile = Path.Combine(apiSlnDir, $"{apiSolutionName}.sln"); - - if (!Directory.Exists(apiSlnDir) || !File.Exists(apiSlnFile)) - { - var bindingsGenerator = new BindingsGenerator(); - - if (!Godot.OS.IsStdoutVerbose()) - bindingsGenerator.LogPrintEnabled = false; - - Error err = bindingsGenerator.GenerateCsApi(apiSlnDir); - if (err != Error.Ok) - { - ShowBuildErrorDialog($"Failed to generate {apiSolutionName} solution. Error: {err}"); - return false; - } - } - - pr.Step($"Building {apiSolutionName} solution", 1); - - if (!BuildApiSolution(apiSlnDir, config)) - return false; - - pr.Step($"Copying {apiName} assembly", 2); - - // Copy the built assembly to the assemblies directory - string apiAssemblyDir = Path.Combine(apiSlnDir, apiName, "bin", config); - if (!CopyApiAssembly(apiAssemblyDir, resAssembliesDir, apiName, apiType)) - return false; - } - - return true; - } - public static bool BuildProjectBlocking(string config, IEnumerable<string> godotDefines) { if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) return true; // No solution to build - string apiConfig = config == "Release" ? "Release" : "Debug"; - - if (!MakeApiAssembly(ApiAssemblyType.Core, apiConfig)) - return false; - - if (!MakeApiAssembly(ApiAssemblyType.Editor, apiConfig)) - return false; + // Make sure to update the API assemblies if they happen to be missing. Just in + // case the user decided to delete them at some point after they were loaded. + Internal.UpdateApiAssembliesFromPrebuilt(); using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1)) { @@ -376,7 +257,7 @@ namespace GodotTools { // Build tool settings - Internal.EditorDef("mono/builds/build_tool", OS.IsWindows() ? BuildTool.MsBuildVs : BuildTool.MsBuildMono); + EditorDef("mono/builds/build_tool", OS.IsWindows() ? BuildTool.MsBuildVs : BuildTool.MsBuildMono); var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); @@ -390,7 +271,7 @@ namespace GodotTools $"{PropNameMsbuildMono},{PropNameXbuild}" }); - Internal.EditorDef("mono/builds/print_build_output", false); + EditorDef("mono/builds/print_build_output", false); } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 955574d5fe..90dec43412 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using GodotTools.Internals; using GodotTools.ProjectEditor; +using static GodotTools.Internals.Globals; using File = GodotTools.Utils.File; using Path = System.IO.Path; using OS = GodotTools.Utils.OS; @@ -26,13 +27,15 @@ namespace GodotTools private MonoDevelopInstance monoDevelopInstance; private MonoDevelopInstance visualStudioForMacInstance; + private WeakRef exportPluginWeak; // TODO Use WeakReference once we have proper serialization + public MonoBottomPanel MonoBottomPanel { get; private set; } private bool CreateProjectSolution() { - using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...", 2)) // TTR("Generating solution...") + using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2)) { - pr.Step("Generating C# project..."); // TTR("Generating C# project...") + pr.Step("Generating C# project...".TTR()); string resourceDir = ProjectSettings.GlobalizePath("res://"); @@ -65,96 +68,28 @@ namespace GodotTools } catch (IOException e) { - ShowErrorDialog($"Failed to save solution. Exception message: {e.Message}"); // TTR + ShowErrorDialog("Failed to save solution. Exception message: ".TTR() + e.Message); return false; } - string apiConfig = "Debug"; - - if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Core, apiConfig)) - return false; - - if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Editor, apiConfig)) - return false; + // Make sure to update the API assemblies if they happen to be missing. Just in + // case the user decided to delete them at some point after they were loaded. + Internal.UpdateApiAssembliesFromPrebuilt(); - pr.Step("Done"); // TTR("Done") + pr.Step("Done".TTR()); // Here, after all calls to progress_task_step CallDeferred(nameof(_RemoveCreateSlnMenuOption)); } else { - ShowErrorDialog("Failed to create C# project."); // TTR + ShowErrorDialog("Failed to create C# project.".TTR()); } return true; } } - private static int _makeApiSolutionsAttempts = 100; - private static bool _makeApiSolutionsRecursionGuard = false; - - private void _MakeApiSolutionsIfNeeded() - { - // I'm sick entirely of ProgressDialog - - if (Internal.IsMessageQueueFlushing() || Engine.GetMainLoop() == null) - { - if (_makeApiSolutionsAttempts == 0) // This better never happen or I swear... - throw new TimeoutException(); - - if (Engine.GetMainLoop() != null) - { - if (!Engine.GetMainLoop().IsConnected("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded))) - Engine.GetMainLoop().Connect("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded)); - } - else - { - CallDeferred(nameof(_MakeApiSolutionsIfNeededImpl)); - } - - _makeApiSolutionsAttempts--; - return; - } - - // Recursion guard needed because signals don't play well with ProgressDialog either, but unlike - // the message queue, with signals the collateral damage should be minimal in the worst case. - if (!_makeApiSolutionsRecursionGuard) - { - _makeApiSolutionsRecursionGuard = true; - - // Oneshot signals don't play well with ProgressDialog either, so we do it this way instead - if (Engine.GetMainLoop().IsConnected("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded))) - Engine.GetMainLoop().Disconnect("idle_frame", this, nameof(_MakeApiSolutionsIfNeeded)); - - _MakeApiSolutionsIfNeededImpl(); - - _makeApiSolutionsRecursionGuard = false; - } - } - - private void _MakeApiSolutionsIfNeededImpl() - { - // If the project has a solution and C# project make sure the API assemblies are present and up to date - - string api_config = "Debug"; - string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, api_config); - - if (!File.Exists(Path.Combine(resAssembliesDir, $"{ApiAssemblyNames.Core}.dll")) || - Internal.MetadataIsApiAssemblyInvalidated(ApiAssemblyType.Core)) - { - if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Core, api_config)) - return; - } - - if (!File.Exists(Path.Combine(resAssembliesDir, $"{ApiAssemblyNames.Editor}.dll")) || - Internal.MetadataIsApiAssemblyInvalidated(ApiAssemblyType.Editor)) - { - if (!GodotSharpBuilds.MakeApiAssembly(ApiAssemblyType.Editor, api_config)) - return; // Redundant? I don't think so! - } - } - private void _RemoveCreateSlnMenuOption() { menuPopup.RemoveItem(menuPopup.GetItemIndex((int) MenuOptions.CreateSln)); @@ -405,7 +340,7 @@ namespace GodotTools MonoBottomPanel = new MonoBottomPanel(); - bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono"); // TTR("Mono") + bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono".TTR()); AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"}); @@ -417,7 +352,7 @@ namespace GodotTools // TODO: Remove or edit this info dialog once Mono support is no longer in alpha { - menuPopup.AddItem("About C# support", (int) MenuOptions.AboutCSharp); // TTR("About C# support") + menuPopup.AddItem("About C# support".TTR(), (int) MenuOptions.AboutCSharp); aboutDialog = new AcceptDialog(); editorBaseControl.AddChild(aboutDialog); aboutDialog.WindowTitle = "Important: C# support is not feature-complete"; @@ -439,7 +374,7 @@ namespace GodotTools var aboutLabel = new Label(); aboutHBox.AddChild(aboutLabel); - aboutLabel.RectMinSize = new Vector2(600, 150) * Internal.EditorScale; + aboutLabel.RectMinSize = new Vector2(600, 150) * EditorScale; aboutLabel.SizeFlagsVertical = (int) Control.SizeFlags.ExpandFill; aboutLabel.Autowrap = true; aboutLabel.Text = @@ -452,7 +387,7 @@ namespace GodotTools " https://github.com/godotengine/godot/issues\n\n" + "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!"; - Internal.EditorDef("mono/editor/show_info_on_start", true); + EditorDef("mono/editor/show_info_on_start", true); // CheckBox in main container aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"}; @@ -462,13 +397,13 @@ namespace GodotTools if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath)) { - // Defer this task because EditorProgress calls Main::iterarion() and the main loop is not yet initialized. - CallDeferred(nameof(_MakeApiSolutionsIfNeeded)); + // Make sure the existing project has Api assembly references configured correctly + CSharpProject.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); } else { bottomPanelBtn.Hide(); - menuPopup.AddItem("Create C# solution", (int) MenuOptions.CreateSln); // TTR("Create C# solution") + menuPopup.AddItem("Create C# solution".TTR(), (int) MenuOptions.CreateSln); } menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed)); @@ -483,7 +418,7 @@ namespace GodotTools AddControlToContainer(CustomControlContainer.Toolbar, buildButton); // External editor settings - Internal.EditorDef("mono/editor/external_editor", ExternalEditor.None); + EditorDef("mono/editor/external_editor", ExternalEditor.None); string settingsHintStr = "Disabled"; @@ -513,11 +448,29 @@ namespace GodotTools }); // Export plugin - AddExportPlugin(new GodotSharpExport()); + var exportPlugin = new GodotSharpExport(); + AddExportPlugin(exportPlugin); + exportPluginWeak = WeakRef(exportPlugin); GodotSharpBuilds.Initialize(); } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (exportPluginWeak != null) + { + // We need to dispose our export plugin before the editor destroys EditorSettings. + // Otherwise, if the GC disposes it at a later time, EditorExportPlatformAndroid + // will be freed after EditorSettings already was, and its device polling thread + // will try to access the EditorSettings singleton, resulting in null dereferencing. + (exportPluginWeak.GetRef() as GodotSharpExport)?.Dispose(); + + exportPluginWeak.Dispose(); + } + } + public void OnBeforeSerialize() { } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj index a0ff8a0df1..01e8c87d14 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -44,6 +44,7 @@ <Compile Include="Internals\GodotSharpDirs.cs" /> <Compile Include="Internals\Internal.cs" /> <Compile Include="Internals\ScriptClassParser.cs" /> + <Compile Include="Internals\Globals.cs" /> <Compile Include="MonoDevelopInstance.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Build\BuildSystem.cs" /> diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index aa52079cf4..0f6f5ffadc 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -1,5 +1,6 @@ using Godot; using GodotTools.Internals; +using static GodotTools.Internals.Globals; namespace GodotTools { @@ -37,7 +38,7 @@ namespace GodotTools watchTimer = new Timer { OneShot = false, - WaitTime = (float) Internal.EditorDef("mono/assembly_watch_interval_sec", 0.5) + WaitTime = (float) EditorDef("mono/assembly_watch_interval_sec", 0.5) }; watchTimer.Connect("timeout", this, nameof(TimerTimeout)); AddChild(watchTimer); diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs new file mode 100644 index 0000000000..793f84fd77 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs @@ -0,0 +1,33 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace GodotTools.Internals +{ + public static class Globals + { + public static float EditorScale => internal_EditorScale(); + + public static object GlobalDef(string setting, object defaultValue, bool restartIfChanged = false) => + internal_GlobalDef(setting, defaultValue, restartIfChanged); + + public static object EditorDef(string setting, object defaultValue, bool restartIfChanged = false) => + internal_EditorDef(setting, defaultValue, restartIfChanged); + + [SuppressMessage("ReSharper", "InconsistentNaming")] + public static string TTR(this string text) => internal_TTR(text); + + // Internal Calls + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern float internal_EditorScale(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern object internal_GlobalDef(string setting, object defaultValue, bool restartIfChanged); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern object internal_EditorDef(string setting, object defaultValue, bool restartIfChanged); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_TTR(string text); + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index 5c7ce832cd..9526dd3c6f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -10,13 +10,8 @@ namespace GodotTools.Internals public const string CSharpLanguageType = "CSharpScript"; public const string CSharpLanguageExtension = "cs"; - public static float EditorScale => internal_EditorScale(); - - public static object GlobalDef(string setting, object defaultValue, bool restartIfChanged = false) => - internal_GlobalDef(setting, defaultValue, restartIfChanged); - - public static object EditorDef(string setting, object defaultValue, bool restartIfChanged = false) => - internal_EditorDef(setting, defaultValue, restartIfChanged); + public static string UpdateApiAssembliesFromPrebuilt() => + internal_UpdateApiAssembliesFromPrebuilt(); public static string FullTemplatesDir => internal_FullTemplatesDir(); @@ -25,14 +20,6 @@ namespace GodotTools.Internals public static bool IsOsxAppBundleInstalled(string bundleId) => internal_IsOsxAppBundleInstalled(bundleId); - public static bool MetadataIsApiAssemblyInvalidated(ApiAssemblyType apiType) => - internal_MetadataIsApiAssemblyInvalidated(apiType); - - public static void MetadataSetApiAssemblyInvalidated(ApiAssemblyType apiType, bool invalidated) => - internal_MetadataSetApiAssemblyInvalidated(apiType, invalidated); - - public static bool IsMessageQueueFlushing() => internal_IsMessageQueueFlushing(); - public static bool GodotIs32Bits() => internal_GodotIs32Bits(); public static bool GodotIsRealTDouble() => internal_GodotIsRealTDouble(); @@ -62,13 +49,7 @@ namespace GodotTools.Internals // Internal Calls [MethodImpl(MethodImplOptions.InternalCall)] - private static extern float internal_EditorScale(); - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern object internal_GlobalDef(string setting, object defaultValue, bool restartIfChanged); - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern object internal_EditorDef(string setting, object defaultValue, bool restartIfChanged); + private static extern string internal_UpdateApiAssembliesFromPrebuilt(); [MethodImpl(MethodImplOptions.InternalCall)] private static extern string internal_FullTemplatesDir(); @@ -80,15 +61,6 @@ namespace GodotTools.Internals private static extern bool internal_IsOsxAppBundleInstalled(string bundleId); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool internal_MetadataIsApiAssemblyInvalidated(ApiAssemblyType apiType); - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void internal_MetadataSetApiAssemblyInvalidated(ApiAssemblyType apiType, bool invalidated); - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool internal_IsMessageQueueFlushing(); - - [MethodImpl(MethodImplOptions.InternalCall)] private static extern bool internal_GodotIs32Bits(); [MethodImpl(MethodImplOptions.InternalCall)] diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs index 300cf7fcb9..53ff0891d5 100644 --- a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs @@ -3,6 +3,7 @@ using System; using System.IO; using Godot.Collections; using GodotTools.Internals; +using static GodotTools.Internals.Globals; using File = GodotTools.Utils.File; using Path = System.IO.Path; @@ -254,7 +255,7 @@ namespace GodotTools panelTabs = new TabContainer { TabAlign = TabContainer.TabAlignEnum.Left, - RectMinSize = new Vector2(0, 228) * Internal.EditorScale, + RectMinSize = new Vector2(0, 228) * EditorScale, SizeFlagsVertical = (int) SizeFlags.ExpandFill }; panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles")); @@ -266,7 +267,7 @@ namespace GodotTools // Builds tab panelBuildsTab = new VBoxContainer { - Name = "Builds", // TTR + Name = "Builds".TTR(), SizeFlagsHorizontal = (int) SizeFlags.ExpandFill }; panelTabs.AddChild(panelBuildsTab); @@ -276,7 +277,7 @@ namespace GodotTools var buildProjectBtn = new Button { - Text = "Build Project", // TTR + Text = "Build Project".TTR(), FocusMode = FocusModeEnum.None }; buildProjectBtn.Connect("pressed", this, nameof(BuildProjectPressed)); @@ -286,7 +287,7 @@ namespace GodotTools warningsBtn = new ToolButton { - Text = "Warnings", // TTR + Text = "Warnings".TTR(), ToggleMode = true, Pressed = true, Visible = false, @@ -297,7 +298,7 @@ namespace GodotTools errorsBtn = new ToolButton { - Text = "Errors", // TTR + Text = "Errors".TTR(), ToggleMode = true, Pressed = true, Visible = false, @@ -310,7 +311,7 @@ namespace GodotTools viewLogBtn = new Button { - Text = "View log", // TTR + Text = "View log".TTR(), FocusMode = FocusModeEnum.None, Visible = false }; diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 1a440e5ced..45037bf637 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -875,14 +875,14 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect da->make_dir("Core"); da->make_dir("ObjectType"); - String core_dir = path_join(p_proj_dir, "Core"); - String obj_type_dir = path_join(p_proj_dir, "ObjectType"); + String core_dir = path::join(p_proj_dir, "Core"); + String obj_type_dir = path::join(p_proj_dir, "ObjectType"); // Generate source file for global scope constants and enums { StringBuilder constants_source; _generate_global_constants(constants_source); - String output_file = path_join(core_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs"); + String output_file = path::join(core_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs"); Error save_err = _save_file(output_file, constants_source); if (save_err != OK) return save_err; @@ -896,7 +896,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect if (itype.api_type == ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs"); Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) @@ -917,7 +917,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect const String &file_name = E->key(); const GodotCsCompressedFile &file_data = E->value(); - String output_file = path_join(core_dir, file_name); + String output_file = path::join(core_dir, file_name); Vector<uint8_t> data; data.resize(file_data.uncompressed_size); @@ -971,7 +971,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); + String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) @@ -996,8 +996,8 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve da->make_dir("Core"); da->make_dir("ObjectType"); - String core_dir = path_join(p_proj_dir, "Core"); - String obj_type_dir = path_join(p_proj_dir, "ObjectType"); + String core_dir = path::join(p_proj_dir, "Core"); + String obj_type_dir = path::join(p_proj_dir, "ObjectType"); for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { const TypeInterface &itype = E.get(); @@ -1005,7 +1005,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve if (itype.api_type != ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs"); Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) @@ -1051,7 +1051,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); + String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) @@ -1064,7 +1064,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve Error BindingsGenerator::generate_cs_api(const String &p_output_dir) { - String output_dir = DirAccess::get_full_path(p_output_dir, DirAccess::ACCESS_FILESYSTEM); + String output_dir = path::abspath(path::realpath(p_output_dir)); DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!da, ERR_CANT_CREATE); @@ -1862,7 +1862,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { output.append("\n#endif // MONO_GLUE_ENABLED\n"); - Error save_err = _save_file(path_join(p_output_dir, "mono_glue.gen.cpp"), output); + Error save_err = _save_file(path::join(p_output_dir, "mono_glue.gen.cpp"), output); if (save_err != OK) return save_err; @@ -2192,7 +2192,7 @@ void BindingsGenerator::_populate_object_type_interfaces() { itype.base_name = ClassDB::get_parent_class(type_cname); itype.is_singleton = Engine::get_singleton()->has_singleton(itype.proxy_name); - itype.is_instantiable = ClassDB::can_instance(type_cname) && !itype.is_singleton; + itype.is_instantiable = class_info->creation_func && !itype.is_singleton; itype.is_reference = ClassDB::is_parent_class(type_cname, name_cache.type_Reference); itype.memory_own = itype.is_reference; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index a3b5b450ef..0014aaca70 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -30,7 +30,6 @@ #include "editor_internal_calls.h" -#include "core/message_queue.h" #include "core/os/os.h" #include "core/version.h" #include "editor/editor_node.h" @@ -231,24 +230,34 @@ uint32_t godot_icall_GodotSharpExport_GetExportedAssemblyDependencies(MonoString return GodotSharpExport::get_exported_assembly_dependencies(project_dll_name, project_dll_src_path, build_config, custom_lib_dir, dependencies); } -float godot_icall_Internal_EditorScale() { +float godot_icall_Globals_EditorScale() { return EDSCALE; } -MonoObject *godot_icall_Internal_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { +MonoObject *godot_icall_Globals_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { String setting = GDMonoMarshal::mono_string_to_godot(p_setting); Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); return GDMonoMarshal::variant_to_mono_object(result); } -MonoObject *godot_icall_Internal_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { +MonoObject *godot_icall_Globals_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { String setting = GDMonoMarshal::mono_string_to_godot(p_setting); Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); - Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); + Variant result = _EDITOR_DEF(setting, default_value, (bool)p_restart_if_changed); return GDMonoMarshal::variant_to_mono_object(result); } +MonoString *godot_icall_Globals_TTR(MonoString *p_text) { + String text = GDMonoMarshal::mono_string_to_godot(p_text); + return GDMonoMarshal::mono_string_from_godot(TTR(text)); +} + +MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt() { + String error_str = GDMono::get_singleton()->update_api_assemblies_from_prebuilt(); + return GDMonoMarshal::mono_string_from_godot(error_str); +} + MonoString *godot_icall_Internal_FullTemplatesDir() { String full_templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); return GDMonoMarshal::mono_string_from_godot(full_templates_dir); @@ -269,18 +278,6 @@ MonoBoolean godot_icall_Internal_IsOsxAppBundleInstalled(MonoString *p_bundle_id #endif } -MonoBoolean godot_icall_Internal_MetadataIsApiAssemblyInvalidated(int32_t p_api_type) { - return GDMono::get_singleton()->metadata_is_api_assembly_invalidated((APIAssembly::Type)p_api_type); -} - -void godot_icall_Internal_MetadataSetApiAssemblyInvalidated(int32_t p_api_type, MonoBoolean p_invalidated) { - GDMono::get_singleton()->metadata_set_api_assembly_invalidated((APIAssembly::Type)p_api_type, (bool)p_invalidated); -} - -MonoBoolean godot_icall_Internal_IsMessageQueueFlushing() { - return (MonoBoolean)MessageQueue::get_singleton()->is_flushing(); -} - MonoBoolean godot_icall_Internal_GodotIs32Bits() { return sizeof(void *) == 4; } @@ -402,15 +399,10 @@ void register_editor_internal_calls() { mono_add_internal_call("GodotTools.GodotSharpExport::internal_GetExportedAssemblyDependencies", (void *)godot_icall_GodotSharpExport_GetExportedAssemblyDependencies); // Internals - mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorScale", (void *)godot_icall_Internal_EditorScale); - mono_add_internal_call("GodotTools.Internals.Internal::internal_GlobalDef", (void *)godot_icall_Internal_GlobalDef); - mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorDef", (void *)godot_icall_Internal_EditorDef); + mono_add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", (void *)godot_icall_Internal_UpdateApiAssembliesFromPrebuilt); mono_add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", (void *)godot_icall_Internal_FullTemplatesDir); mono_add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", (void *)godot_icall_Internal_SimplifyGodotPath); mono_add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", (void *)godot_icall_Internal_IsOsxAppBundleInstalled); - mono_add_internal_call("GodotTools.Internals.Internal::internal_MetadataIsApiAssemblyInvalidated", (void *)godot_icall_Internal_MetadataIsApiAssemblyInvalidated); - mono_add_internal_call("GodotTools.Internals.Internal::internal_MetadataSetApiAssemblyInvalidated", (void *)godot_icall_Internal_MetadataSetApiAssemblyInvalidated); - mono_add_internal_call("GodotTools.Internals.Internal::internal_IsMessageQueueFlushing", (void *)godot_icall_Internal_IsMessageQueueFlushing); mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", (void *)godot_icall_Internal_GodotIs32Bits); mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", (void *)godot_icall_Internal_GodotIsRealTDouble); mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", (void *)godot_icall_Internal_GodotMainIteration); @@ -424,6 +416,12 @@ void register_editor_internal_calls() { mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing); mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot); + // Globals + mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale); + mono_add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", (void *)godot_icall_Globals_GlobalDef); + mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", (void *)godot_icall_Globals_EditorDef); + mono_add_internal_call("GodotTools.Internals.Globals::internal_TTR", (void *)godot_icall_Globals_TTR); + // Utils.OS mono_add_internal_call("GodotTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName); } |