Beispiel #1
0
        public void _ExportBeginImpl(string[] features, bool isDebug, string path, int flags)
        {
            // TODO Right now there is no way to stop the export process with an error

            if (File.Exists(GodotSharpDirs.ProjectSlnPath))
            {
                string buildConfig = isDebug ? "Debug" : "Release";

                string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}");
                CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath);

                AddFile(scriptsMetadataPath, scriptsMetadataPath);

                // Turn export features into defines
                var godotDefines = features;

                if (!BuildManager.BuildProjectBlocking(buildConfig, godotDefines))
                {
                    GD.PushError("Failed to build project");
                    return;
                }

                // Add dependency assemblies

                var dependencies = new Godot.Collections.Dictionary <string, string>();

                var projectDllName = (string)ProjectSettings.GetSetting("application/config/name");
                if (projectDllName.Empty())
                {
                    projectDllName = "UnnamedProject";
                }

                string projectDllSrcDir  = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig);
                string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll");

                dependencies[projectDllName] = projectDllSrcPath;

                {
                    string templatesDir  = Internal.FullTemplatesDir;
                    string androidBclDir = Path.Combine(templatesDir, "android-bcl");

                    string customLibDir = features.Contains("Android") && Directory.Exists(androidBclDir) ? androidBclDir : string.Empty;

                    GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, customLibDir, dependencies);
                }

                string apiConfig        = isDebug ? "Debug" : "Release";
                string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, apiConfig);

                foreach (var dependency in dependencies)
                {
                    string dependSrcPath = dependency.Value;
                    string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
                    AddFile(dependSrcPath, dependDstPath);
                }
            }

            // Mono specific export template extras (data dir)
            ExportDataDirectory(features, isDebug, path);
        }
        private bool CreateProjectSolution()
        {
            using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2))
            {
                pr.Step("Generating C# project...".TTR());

                string resourceDir = ProjectSettings.GlobalizePath("res://");

                string path = resourceDir;
                string name = GodotSharpDirs.ProjectAssemblyName;

                string guid = CsProjOperations.GenerateGameProject(path, name);

                if (guid.Length > 0)
                {
                    var solution = new DotNetSolution(name)
                    {
                        DirectoryPath = path
                    };

                    var projectInfo = new DotNetSolution.ProjectInfo
                    {
                        Guid = guid,
                        PathRelativeToSolution = name + ".csproj",
                        Configs = new List <string> {
                            "Debug", "ExportDebug", "ExportRelease"
                        }
                    };

                    solution.AddNewProject(name, projectInfo);

                    try
                    {
                        solution.Save();
                    }
                    catch (IOException e)
                    {
                        ShowErrorDialog("Failed to save solution. Exception message: ".TTR() + e.Message);
                        return(false);
                    }

                    pr.Step("Done".TTR());

                    // Here, after all calls to progress_task_step
                    CallDeferred(nameof(_RemoveCreateSlnMenuOption));
                }
                else
                {
                    ShowErrorDialog("Failed to create C# project.".TTR());
                }

                return(true);
            }
        }
Beispiel #3
0
        public void BuildProjectPressed()
        {
            if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
            {
                return; // No solution to build
            }
            string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
            string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");

            CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);

            if (File.Exists(editorScriptsMetadataPath))
            {
                try
                {
                    File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
                }
                catch (IOException e)
                {
                    GD.PushError($"Failed to copy scripts metadata file. Exception message: {e.Message}");
                    return;
                }
            }

            var godotDefines = new[]
            {
                OS.GetName(),
                Internal.GodotIs32Bits() ? "32" : "64"
            };

            bool buildSuccess = BuildManager.BuildProjectBlocking("Debug", godotDefines);

            if (!buildSuccess)
            {
                return;
            }

            // Notify running game for hot-reload
            Internal.EditorDebuggerNodeReloadScripts();

            // Hot-reload in the editor
            GodotSharpEditor.Instance.GetNode <HotReloadAssemblyWatcher>("HotReloadAssemblyWatcher").RestartTimer();

            if (Internal.IsAssembliesReloadingNeeded())
            {
                Internal.ReloadAssemblies(softReload: false);
            }
        }
        public static bool EditorBuildCallback()
        {
            if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
            {
                return(true); // No solution to build
            }
            string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
            string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");

            CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);

            if (File.Exists(editorScriptsMetadataPath))
            {
                File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
            }

            var currentPlayRequest = GodotSharpEditor.Instance.CurrentPlaySettings;

            if (currentPlayRequest != null)
            {
                if (currentPlayRequest.Value.HasDebugger)
                {
                    // Set the environment variable that will tell the player to connect to the IDE debugger
                    // TODO: We should probably add a better way to do this
                    Environment.SetEnvironmentVariable("GODOT_MONO_DEBUGGER_AGENT",
                                                       "--debugger-agent=transport=dt_socket" +
                                                       $",address={currentPlayRequest.Value.DebuggerHost}:{currentPlayRequest.Value.DebuggerPort}" +
                                                       ",server=n");
                }

                if (!currentPlayRequest.Value.BuildBeforePlaying)
                {
                    return(true); // Requested play from an external editor/IDE which already built the project
                }
            }

            var godotDefines = new[]
            {
                Godot.OS.GetName(),
                Internal.GodotIs32Bits() ? "32" : "64"
            };

            return(BuildProjectBlocking("Debug", godotDefines));
        }
Beispiel #5
0
        public static bool EditorBuildCallback()
        {
            if (!File.Exists(GodotSharpDirs.ProjectSlnPath))
            {
                return(true); // No solution to build
            }
            string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor");
            string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player");

            CsProjOperations.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath);

            if (File.Exists(editorScriptsMetadataPath))
            {
                File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
            }

            if (GodotSharpEditor.Instance.SkipBuildBeforePlaying)
            {
                return(true); // Requested play from an external editor/IDE which already built the project
            }
            return(BuildProjectBlocking("Debug"));
        }
Beispiel #6
0
        private bool CreateProjectSolution()
        {
            using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 3))
            {
                pr.Step("Generating C# project...".TTR());

                string resourceDir = ProjectSettings.GlobalizePath("res://");

                string path = resourceDir;
                string name = (string)ProjectSettings.GetSetting("application/config/name");
                if (name.Empty())
                {
                    name = "UnnamedProject";
                }

                string guid = CsProjOperations.GenerateGameProject(path, name);

                if (guid.Length > 0)
                {
                    var solution = new DotNetSolution(name)
                    {
                        DirectoryPath = path
                    };

                    var projectInfo = new DotNetSolution.ProjectInfo
                    {
                        Guid = guid,
                        PathRelativeToSolution = name + ".csproj",
                        Configs = new List <string> {
                            "Debug", "Release", "Tools"
                        }
                    };

                    solution.AddNewProject(name, projectInfo);

                    try
                    {
                        solution.Save();
                    }
                    catch (IOException e)
                    {
                        ShowErrorDialog("Failed to save solution. Exception message: ".TTR() + e.Message);
                        return(false);
                    }

                    pr.Step("Updating Godot API assemblies...".TTR());

                    string debugApiAssembliesError = Internal.UpdateApiAssembliesFromPrebuilt("Debug");

                    if (!string.IsNullOrEmpty(debugApiAssembliesError))
                    {
                        ShowErrorDialog("Failed to update the Godot API assemblies: " + debugApiAssembliesError);
                        return(false);
                    }

                    string releaseApiAssembliesError = Internal.UpdateApiAssembliesFromPrebuilt("Release");

                    if (!string.IsNullOrEmpty(releaseApiAssembliesError))
                    {
                        ShowErrorDialog("Failed to update the Godot API assemblies: " + releaseApiAssembliesError);
                        return(false);
                    }

                    pr.Step("Done".TTR());

                    // Here, after all calls to progress_task_step
                    CallDeferred(nameof(_RemoveCreateSlnMenuOption));
                }
                else
                {
                    ShowErrorDialog("Failed to create C# project.".TTR());
                }

                return(true);
            }
        }
Beispiel #7
0
        public override void EnablePlugin()
        {
            base.EnablePlugin();

            if (Instance != null)
            {
                throw new InvalidOperationException();
            }
            Instance = this;

            var editorInterface   = GetEditorInterface();
            var editorBaseControl = editorInterface.GetBaseControl();

            editorSettings = editorInterface.GetEditorSettings();

            errorDialog = new AcceptDialog();
            editorBaseControl.AddChild(errorDialog);

            BottomPanel = new BottomPanel();

            bottomPanelBtn = AddControlToBottomPanel(BottomPanel, "Mono".TTR());

            AddChild(new HotReloadAssemblyWatcher {
                Name = "HotReloadAssemblyWatcher"
            });

            menuPopup = new PopupMenu();
            menuPopup.Hide();
            menuPopup.SetAsToplevel(true);

            AddToolSubmenuItem("Mono", menuPopup);

            // TODO: Remove or edit this info dialog once Mono support is no longer in alpha
            {
                menuPopup.AddItem("About C# support".TTR(), (int)MenuOptions.AboutCSharp);
                aboutDialog = new AcceptDialog();
                editorBaseControl.AddChild(aboutDialog);
                aboutDialog.WindowTitle = "Important: C# support is not feature-complete";

                // We don't use DialogText as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox
                // we'll add. Instead we add containers and a new autowrapped Label inside.

                // Main VBoxContainer (icon + label on top, checkbox at bottom)
                var aboutVBox = new VBoxContainer();
                aboutDialog.AddChild(aboutVBox);

                // HBoxContainer for icon + label
                var aboutHBox = new HBoxContainer();
                aboutVBox.AddChild(aboutHBox);

                var aboutIcon = new TextureRect();
                aboutIcon.Texture = aboutIcon.GetIcon("NodeWarning", "EditorIcons");
                aboutHBox.AddChild(aboutIcon);

                var aboutLabel = new Label();
                aboutHBox.AddChild(aboutLabel);
                aboutLabel.RectMinSize       = new Vector2(600, 150) * EditorScale;
                aboutLabel.SizeFlagsVertical = (int)Control.SizeFlags.ExpandFill;
                aboutLabel.Autowrap          = true;
                aboutLabel.Text =
                    "C# support in Godot Engine is in late alpha stage and, while already usable, " +
                    "it is not meant for use in production.\n\n" +
                    "Projects can be exported to Linux, macOS, Windows and Android, but not yet to iOS, HTML5 or UWP. " +
                    "Bugs and usability issues will be addressed gradually over future releases, " +
                    "potentially including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" +
                    "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, MSBuild version, IDE, etc.:\n\n" +
                    "        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!";

                EditorDef("mono/editor/show_info_on_start", true);

                // CheckBox in main container
                aboutDialogCheckBox = new CheckBox {
                    Text = "Show this warning when starting the editor"
                };
                aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart));
                aboutVBox.AddChild(aboutDialogCheckBox);
            }

            if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath))
            {
                // Make sure the existing project has Api assembly references configured correctly
                CsProjOperations.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
            }
            else
            {
                bottomPanelBtn.Hide();
                menuPopup.AddItem("Create C# solution".TTR(), (int)MenuOptions.CreateSln);
            }

            menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed));

            var buildButton = new ToolButton
            {
                Text        = "Build",
                HintTooltip = "Build solution",
                FocusMode   = Control.FocusModeEnum.None
            };

            buildButton.Connect("pressed", this, nameof(_BuildSolutionPressed));
            AddControlToContainer(CustomControlContainer.Toolbar, buildButton);

            // External editor settings
            EditorDef("mono/editor/external_editor", ExternalEditorId.None);

            string settingsHintStr = "Disabled";

            if (OS.IsWindows)
            {
                settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
                                   $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                   $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
            }
            else if (OS.IsOSX)
            {
                settingsHintStr += $",Visual Studio:{(int)ExternalEditorId.VisualStudioForMac}" +
                                   $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
                                   $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                   $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
            }
            else if (OS.IsUnixLike())
            {
                settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
                                   $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
                                   $",JetBrains Rider:{(int)ExternalEditorId.Rider}";
            }

            editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
            {
                ["type"]        = Variant.Type.Int,
                ["name"]        = "mono/editor/external_editor",
                ["hint"]        = PropertyHint.Enum,
                ["hint_string"] = settingsHintStr
            });

            // Export plugin
            var exportPlugin = new ExportPlugin();

            AddExportPlugin(exportPlugin);
            exportPlugin.RegisterExportSettings();
            exportPluginWeak = WeakRef(exportPlugin);

            BuildManager.Initialize();
            RiderPathManager.Initialize();

            GodotIdeManager = new GodotIdeManager();
            AddChild(GodotIdeManager);
        }