From 96aa458dd12924c3f69b94f690350de5e49ba691 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 3 Apr 2016 14:14:17 +0200 Subject: [PATCH] Add an abort button for interrupting python scripts during execution --- .../Windows/Dialogs/PythonShell.Designer.cs | 14 +++++++++- renderdocui/Windows/Dialogs/PythonShell.cs | 28 +++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/renderdocui/Windows/Dialogs/PythonShell.Designer.cs b/renderdocui/Windows/Dialogs/PythonShell.Designer.cs index 9a194504f..addd94baa 100644 --- a/renderdocui/Windows/Dialogs/PythonShell.Designer.cs +++ b/renderdocui/Windows/Dialogs/PythonShell.Designer.cs @@ -52,6 +52,7 @@ this.openDialog = new System.Windows.Forms.OpenFileDialog(); this.newScript = new System.Windows.Forms.ToolStripButton(); this.linenumTimer = new System.Windows.Forms.Timer(this.components); + this.abortButton = new System.Windows.Forms.ToolStripButton(); toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); toolStrip1 = new System.Windows.Forms.ToolStrip(); toolStripContainer1.ContentPanel.SuspendLayout(); @@ -133,7 +134,8 @@ this.openButton, this.saveAs, this.toolStripSeparator2, - this.runButton}); + this.runButton, + this.abortButton}); this.toolStrip2.Location = new System.Drawing.Point(0, 0); this.toolStrip2.Name = "toolStrip2"; this.toolStrip2.Size = new System.Drawing.Size(306, 25); @@ -308,6 +310,15 @@ this.linenumTimer.Interval = 500; this.linenumTimer.Tick += new System.EventHandler(this.linenumTimer_Tick); // + // abortButton + // + this.abortButton.Image = global::renderdocui.Properties.Resources.delete; + this.abortButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.abortButton.Name = "abortButton"; + this.abortButton.Size = new System.Drawing.Size(54, 22); + this.abortButton.Text = "Abort"; + this.abortButton.Click += new System.EventHandler(this.abortButton_Click); + // // PythonShell // this.AllowDrop = true; @@ -364,6 +375,7 @@ private System.Windows.Forms.OpenFileDialog openDialog; private System.Windows.Forms.ToolStripButton newScript; private System.Windows.Forms.Timer linenumTimer; + private System.Windows.Forms.ToolStripButton abortButton; } diff --git a/renderdocui/Windows/Dialogs/PythonShell.cs b/renderdocui/Windows/Dialogs/PythonShell.cs index f533da869..7cd936417 100644 --- a/renderdocui/Windows/Dialogs/PythonShell.cs +++ b/renderdocui/Windows/Dialogs/PythonShell.cs @@ -70,6 +70,8 @@ namespace renderdocui.Windows.Dialogs mode_Changed(shellMode, null); clearCmd_Click(null, null); + + EnableButtons(true); } void scriptEditor_KeyDown(object sender, KeyEventArgs e) @@ -118,6 +120,8 @@ namespace renderdocui.Windows.Dialogs return scope; } + private Thread pythonThread = null; + private MemoryStream stdout = null; private StreamWriter stdoutwriter = null; private StreamReader stdoutreader = null; @@ -333,6 +337,13 @@ namespace renderdocui.Windows.Dialogs shellMode.Enabled = scriptMode.Enabled = newScript.Enabled = openButton.Enabled = saveAs.Enabled = runButton.Enabled = enable; + abortButton.Enabled = !enable; + } + + private void abortButton_Click(object sender, EventArgs e) + { + if (pythonThread != null) + pythonThread.Abort(); } private void runButton_Click(object sender, EventArgs e) @@ -351,18 +362,29 @@ namespace renderdocui.Windows.Dialogs linenumTimer.Enabled = true; linenumTimer.Start(); - Thread th = Helpers.NewThread(new ThreadStart(() => + pythonThread = Helpers.NewThread(new ThreadStart(() => { pythonengine.SetTrace(PythonTrace); + string output = ""; // ignore output, the trace handler above will print output - string output = Execute(pythonengine, scriptscope, script); + try + { + output = Execute(pythonengine, scriptscope, script); + } + catch (ThreadAbortException) + { + // python was interrupted + Thread.ResetAbort(); + } linenumTimer.Stop(); pythonengine.SetTrace(null); this.BeginInvoke(new Action(() => { + pythonThread = null; + scriptOutput.Text += output; SetLineNumber(linenum); @@ -371,7 +393,7 @@ namespace renderdocui.Windows.Dialogs })); })); - th.Start(); + pythonThread.Start(); } private string ValidData(IDataObject d)