From 71ad1199d8bbc724886dbb185ad368ab442268c2 Mon Sep 17 00:00:00 2001 From: MaxED Date: Sun, 23 Mar 2014 09:08:51 +0000 Subject: [PATCH] The editor no longer locks up while testing the map. --- Source/Core/Config/ProgramConfiguration.cs | 2 - Source/Core/Editing/ClassicMode.cs | 8 +- Source/Core/Editing/EditMode.cs | 4 +- Source/Core/General/General.cs | 60 +++++++--- Source/Core/General/Launcher.cs | 107 +++++++++--------- Source/Core/VisualModes/VisualMode.cs | 8 +- Source/Core/Windows/MainForm.cs | 3 + .../ClassicModes/BaseClassicMode.cs | 4 +- 8 files changed, 118 insertions(+), 78 deletions(-) diff --git a/Source/Core/Config/ProgramConfiguration.cs b/Source/Core/Config/ProgramConfiguration.cs index ae635977..ba449bd8 100644 --- a/Source/Core/Config/ProgramConfiguration.cs +++ b/Source/Core/Config/ProgramConfiguration.cs @@ -103,7 +103,6 @@ namespace CodeImp.DoomBuilder.Config private int gzMaxDynamicLights; private float gzDynamicLightRadius; private float gzDynamicLightIntensity; - private bool gzTestFromCurrentPosition; private bool gzStretchModels; private float gzVertexScale2D; private bool gzShowVisualVertices; @@ -182,7 +181,6 @@ namespace CodeImp.DoomBuilder.Config public bool GZToolbarGZDoom { get { return gzToolbarGZDoom; } internal set { gzToolbarGZDoom = value; } } public bool GZSynchCameras { get { return gzSynchCameras; } internal set { gzSynchCameras = value; } } public bool GZShowEventLines { get { return gzShowEventLines; } internal set { gzShowEventLines = value; } } - public bool GZTestFromCurrentPosition { get { return gzTestFromCurrentPosition; } internal set { gzTestFromCurrentPosition = value; } } public bool GZOldHighlightMode { get { return gzOldHighlightMode; } internal set { gzOldHighlightMode = value; } } public int GZMaxDynamicLights { get { return gzMaxDynamicLights; } internal set { gzMaxDynamicLights = value; } } public float GZDynamicLightRadius { get { return gzDynamicLightRadius; } internal set { gzDynamicLightRadius = value; } } diff --git a/Source/Core/Editing/ClassicMode.cs b/Source/Core/Editing/ClassicMode.cs index ca0a0ff7..a7565514 100644 --- a/Source/Core/Editing/ClassicMode.cs +++ b/Source/Core/Editing/ClassicMode.cs @@ -607,8 +607,8 @@ namespace CodeImp.DoomBuilder.Editing } //mxd - public override bool OnMapTestBegin() { - if (General.Settings.GZTestFromCurrentPosition) { + public override bool OnMapTestBegin(bool testFromCurrentPosition) { + if(testFromCurrentPosition) { if(!mouseinside){ General.MainWindow.DisplayStatus(StatusType.Warning, "Can't test from current position: mouse is outside editing vindow!"); return false; @@ -658,8 +658,8 @@ namespace CodeImp.DoomBuilder.Editing return true; } - public override void OnMapTestEnd() { - if (General.Settings.GZTestFromCurrentPosition) { + public override void OnMapTestEnd(bool testFromCurrentPosition) { + if (testFromCurrentPosition) { //restore position playerStart.Move(playerStartPosition); playerStart = null; diff --git a/Source/Core/Editing/EditMode.cs b/Source/Core/Editing/EditMode.cs index 8694a35e..96354956 100644 --- a/Source/Core/Editing/EditMode.cs +++ b/Source/Core/Editing/EditMode.cs @@ -212,8 +212,8 @@ namespace CodeImp.DoomBuilder.Editing public virtual void OnMapSetChangeEnd() { } //mxd. map testing events - public virtual bool OnMapTestBegin() { return true; } //called before test map is launched. Returns false if map launch is impossible - public virtual void OnMapTestEnd() { } //called after game engine is closed + public virtual bool OnMapTestBegin(bool testFromCurrentPosition) { return true; } //called before test map is launched. Returns false if map launch is impossible + public virtual void OnMapTestEnd(bool testFromCurrentPosition) { } //called after game engine is closed #endregion } diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index deedcbc7..1ca32428 100644 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -982,6 +982,12 @@ namespace CodeImp.DoomBuilder [BeginAction("newmap")] internal static void NewMap() { + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot create a map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); + return; + } + MapOptions newoptions = new MapOptions(); MapOptionsForm optionswindow; @@ -1063,6 +1069,12 @@ namespace CodeImp.DoomBuilder internal static void ActionCloseMap() { CloseMap(); } internal static bool CloseMap() { + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot close the map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); + return false; + } + // Cancel volatile mode, if any General.Editing.DisengageVolatileMode(); @@ -1110,6 +1122,12 @@ namespace CodeImp.DoomBuilder [BeginAction("openmap")] internal static void OpenMap() { + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot open a map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); + return; + } + // Cancel volatile mode, if any General.Editing.DisengageVolatileMode(); @@ -1140,6 +1158,12 @@ namespace CodeImp.DoomBuilder // This loads a different map from same wad file [BeginAction("openmapincurrentwad")] internal static void OpenMapInCurrentWad() { + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot change the map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); + return; + } + if (map == null || string.IsNullOrEmpty(map.FilePathName) || !File.Exists(map.FilePathName)){ Interface.DisplayStatus(StatusType.Warning, "Unable to open map from current WAD!"); return; @@ -1290,10 +1314,14 @@ namespace CodeImp.DoomBuilder internal static void ActionSaveMap() { SaveMap(); } internal static bool SaveMap() { - bool result = false; - - if(map == null) + //mxd + if (map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot save the map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); return false; + } + + if(map == null) return false; + bool result = false; // Cancel volatile mode, if any General.Editing.DisengageVolatileMode(); @@ -1348,17 +1376,20 @@ namespace CodeImp.DoomBuilder internal static void ActionSaveMapAs() { SaveMapAs(); } internal static bool SaveMapAs() { - SaveFileDialog savefile; - bool result = false; - - if(map == null) + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot save the map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); return false; + } + + if(map == null) return false; + bool result = false; // Cancel volatile mode, if any General.Editing.DisengageVolatileMode(); // Show save as dialog - savefile = new SaveFileDialog(); + SaveFileDialog savefile = new SaveFileDialog(); savefile.Filter = "Doom WAD Files (*.wad)|*.wad"; savefile.Title = "Save Map As"; savefile.AddExtension = true; @@ -1422,17 +1453,20 @@ namespace CodeImp.DoomBuilder internal static void ActionSaveMapInto() { SaveMapInto(); } internal static bool SaveMapInto() { - SaveFileDialog savefile; - bool result = false; - - if(map == null) + //mxd + if(map.Launcher.GameEngineRunning) { + ShowWarningMessage("Cannot save the map while game engine is running" + Environment.NewLine + "Please close '" + map.ConfigSettings.TestProgram + "' first.", MessageBoxButtons.OK); return false; + } + + if(map == null) return false; + bool result = false; // Cancel volatile mode, if any General.Editing.DisengageVolatileMode(); // Show save as dialog - savefile = new SaveFileDialog(); + SaveFileDialog savefile = new SaveFileDialog(); savefile.Filter = "Doom WAD Files (*.wad)|*.wad"; savefile.Title = "Save Map Into"; savefile.AddExtension = true; diff --git a/Source/Core/General/Launcher.cs b/Source/Core/General/Launcher.cs index 79703494..496df2ce 100644 --- a/Source/Core/General/Launcher.cs +++ b/Source/Core/General/Launcher.cs @@ -39,15 +39,18 @@ namespace CodeImp.DoomBuilder #region ================== Variables private string tempwad; - + private Process process; //mxd private bool isdisposed; + + delegate void EngineExitedCallback(); //mxd #endregion #region ================== Properties public string TempWAD { get { return tempwad; } } - + public bool GameEngineRunning { get { return process != null; } } //mxd + #endregion #region ================== Constructor / Destructor @@ -70,6 +73,12 @@ namespace CodeImp.DoomBuilder { // Unbind actions General.Actions.UnbindMethods(this); + + //mxd. Terminate process? + if (process != null) { + process.CloseMainWindow(); + process.Close(); + } // Remove temporary file try { File.Delete(tempwad); } @@ -227,29 +236,28 @@ namespace CodeImp.DoomBuilder [BeginAction("testmap")] public void Test() { - General.Settings.GZTestFromCurrentPosition = false; //mxd - if(!General.Editing.Mode.OnMapTestBegin()) return; //mxd + if(!General.Editing.Mode.OnMapTestBegin(false)) return; //mxd TestAtSkill(General.Map.ConfigSettings.TestSkill); - General.Editing.Mode.OnMapTestEnd(); //mxd + General.Editing.Mode.OnMapTestEnd(false); //mxd } //mxd [BeginAction("testmapfromview")] public void TestFromView() { - General.Settings.GZTestFromCurrentPosition = true; - if(!General.Editing.Mode.OnMapTestBegin()) return; //mxd - - General.MainWindow.StopProcessing(); + if(!General.Editing.Mode.OnMapTestBegin(true)) return; TestAtSkill(General.Map.ConfigSettings.TestSkill); - - General.Editing.Mode.OnMapTestEnd(); //mxd - General.MainWindow.EnableProcessing(); - General.MainWindow.FocusDisplay(); + General.Editing.Mode.OnMapTestEnd(true); } // This saves the map to a temporary file and launches a test wit hthe given skill public void TestAtSkill(int skill) { + //mxd + if (process != null) { + General.ShowWarningMessage("Game engine is already running." + Environment.NewLine + " Please close '" + General.Map.ConfigSettings.TestProgram + "' before testing again", MessageBoxButtons.OK); + return; + } + Cursor oldcursor = Cursor.Current; // Check if configuration is OK @@ -310,66 +318,63 @@ namespace CodeImp.DoomBuilder // Output info General.WriteLogLine("Running test program: " + processinfo.FileName); General.WriteLogLine("Program parameters: " + processinfo.Arguments); - - // Disable interface - General.MainWindow.DisplayStatus(StatusType.Busy, "Waiting for game application to finish..."); + General.MainWindow.DisplayStatus(StatusType.Info, "Launching " + processinfo.FileName + "..."); try { // Start the program - Process process = Process.Start(processinfo); - - // Wait for program to complete - while(!process.WaitForExit(10)) - { - //General.MainWindow.Update(); //mxd - } - - // Done - TimeSpan deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks); - General.WriteLogLine("Test program has finished."); - General.WriteLogLine("Run time: " + deltatime.TotalSeconds.ToString("###########0.00") + " seconds"); + process = Process.Start(processinfo); + process.EnableRaisingEvents = true; //mxd + process.Exited += ProcessOnExited; //mxd + Cursor.Current = oldcursor; //mxd } catch(Exception e) { // Unable to start the program General.ShowErrorMessage("Unable to start the test program, " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK); } - - General.MainWindow.DisplayReady(); } else { General.MainWindow.DisplayStatus(StatusType.Warning, "Unable to test the map due to script errors."); } } - + } + + //mxd + private void testingFinished() { + //Done + TimeSpan deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks); + process = null; + General.WriteLogLine("Test program has finished."); + General.WriteLogLine("Run time: " + deltatime.TotalSeconds.ToString("###########0.00") + " seconds"); + General.MainWindow.DisplayReady(); + // Clean up temp file CleanTempFile(General.Map); - - // Done - int retries = 0; //mxd - while(!General.Map.Graphics.CheckAvailability()) { - Thread.Sleep(100); - - if (retries++ > 50) { //that's 5 seconds, right? - DialogResult result = General.ShowErrorMessage("Unable to reset D3D device." + Environment.NewLine + "Press Abort to quit," + Environment.NewLine + "Retry to wait and retry," + Environment.NewLine + "Ignore to proceed anyway (high chances of D3DException)", MessageBoxButtons.AbortRetryIgnore); - if(result == DialogResult.Abort) { - General.Exit(true); - } else if (result == DialogResult.Retry) { - retries = 0; - } else { - break; - } - } - } General.Plugins.OnMapSaveEnd(SavePurpose.Testing); - General.MainWindow.RedrawDisplay(); General.MainWindow.FocusDisplay(); - Cursor.Current = oldcursor; } - + + //mxd + public void StopGameEngine() { + //mxd. Terminate process? + if(process != null) { + process.CloseMainWindow(); + process.Close(); + process = null; + + // Remove temporary file + try { if(File.Exists(tempwad)) File.Delete(tempwad); } catch(Exception) { } + } + } + + //mxd + private void ProcessOnExited(object sender, EventArgs eventArgs) { + General.MainWindow.Invoke(new EngineExitedCallback(testingFinished)); + } + // This deletes the previous temp file and creates a new, empty temp file private void CleanTempFile(MapManager manager) { diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs index 9d1836c1..79c91fb8 100644 --- a/Source/Core/VisualModes/VisualMode.cs +++ b/Source/Core/VisualModes/VisualMode.cs @@ -265,8 +265,8 @@ namespace CodeImp.DoomBuilder.VisualModes } //mxd - public override bool OnMapTestBegin() { - if (General.Settings.GZTestFromCurrentPosition) { + public override bool OnMapTestBegin(bool testFromCurrentPosition) { + if (testFromCurrentPosition) { //find Single Player Start. Should have Type 1 in all games Thing start = null; @@ -317,8 +317,8 @@ namespace CodeImp.DoomBuilder.VisualModes } //mxd - public override void OnMapTestEnd() { - if (General.Settings.GZTestFromCurrentPosition) { + public override void OnMapTestEnd(bool testFromCurrentPosition) { + if (testFromCurrentPosition) { //restore position playerStart.Move(playerStartPosition); playerStart.Rotate(playerStartAngle); diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 8ba410fe..84df93f5 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -586,6 +586,9 @@ namespace CodeImp.DoomBuilder.Windows if(e.CloseReason != CloseReason.ApplicationExitCall) { + //mxd + if(General.Map != null && General.Map.Launcher.GameEngineRunning) General.Map.Launcher.StopGameEngine(); + // Close the map if(General.CloseMap()) { diff --git a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs index c1f8a564..438c7d8b 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs @@ -161,8 +161,8 @@ namespace CodeImp.DoomBuilder.BuilderModes } //mxd - public override void OnMapTestEnd() { - base.OnMapTestEnd(); + public override void OnMapTestEnd(bool testFromCurrentPosition) { + base.OnMapTestEnd(testFromCurrentPosition); General.Interface.RedrawDisplay(); // Redraw display to hide changes :) }