Don't launch blocking execute call on UI thread, pop up progress ticker

* This most commonly happens launching an Android program that takes a
  while to launch, or if you're launching a program with the delay for
  debugger option set.
* Instead of the whole UI hanging, you'll get a progress dialog to
  appear while it's waiting.
This commit is contained in:
baldurk
2017-02-24 17:34:02 +00:00
parent 0ff1ff0d03
commit f76a4cc339
7 changed files with 172 additions and 92 deletions
+14 -10
View File
@@ -259,8 +259,10 @@ namespace renderdocui.Windows.Dialogs
#region Callbacks
public delegate LiveCapture OnCaptureMethod(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts);
public delegate LiveCapture OnInjectMethod(UInt32 PID, EnvironmentModification[] env, string name, CaptureOptions opts);
public delegate void OnConnectionEstablishedMethod(LiveCapture live);
public delegate void OnCaptureMethod(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts, OnConnectionEstablishedMethod cb);
public delegate void OnInjectMethod(UInt32 PID, EnvironmentModification[] env, string name, CaptureOptions opts, OnConnectionEstablishedMethod cb);
private OnCaptureMethod m_CaptureCallback = null;
private OnInjectMethod m_InjectCallback = null;
@@ -430,10 +432,11 @@ namespace renderdocui.Windows.Dialogs
string cmdLine = cmdline.Text;
var live = m_CaptureCallback(exe, workingDir, cmdLine, GetSettings().Environment, GetSettings().Options);
if (queueFrameCap.Checked && live != null)
live.QueueCapture((int)queuedCapFrame.Value);
m_CaptureCallback(exe, workingDir, cmdLine, GetSettings().Environment, GetSettings().Options, (LiveCapture live) =>
{
if (queueFrameCap.Checked)
live.QueueCapture((int)queuedCapFrame.Value);
});
}
private void OnInject()
@@ -445,10 +448,11 @@ namespace renderdocui.Windows.Dialogs
string name = item.SubItems[1].Text;
UInt32 PID = (UInt32)item.Tag;
var live = m_InjectCallback(PID, GetSettings().Environment, name, GetSettings().Options);
if (queueFrameCap.Checked && live != null)
live.QueueCapture((int)queuedCapFrame.Value);
m_InjectCallback(PID, GetSettings().Environment, name, GetSettings().Options, (LiveCapture live) =>
{
if (queueFrameCap.Checked)
live.QueueCapture((int)queuedCapFrame.Value);
});
}
}
+66 -24
View File
@@ -1019,48 +1019,90 @@ namespace renderdocui.Windows
return "";
}
private LiveCapture OnCaptureTrigger(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts)
private void OnCaptureTrigger(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts, Dialogs.CaptureDialog.OnConnectionEstablishedMethod callback)
{
if (!PromptCloseLog())
return null;
return;
string logfile = m_Core.TempLogFilename(Path.GetFileNameWithoutExtension(exe));
StaticExports.SetConfigSetting("MaxConnectTimeout", m_Core.Config.MaxConnectTimeout.ToString());
UInt32 ret = m_Core.Renderer.ExecuteAndInject(exe, workingDir, cmdLine, env, logfile, opts);
if (ret == 0)
Thread th = Helpers.NewThread(new ThreadStart(() =>
{
MessageBox.Show(string.Format("Error launching {0} for capture.\n\nCheck diagnostic log in Help menu for more details.", exe),
"Error kicking capture", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
UInt32 ret = m_Core.Renderer.ExecuteAndInject(exe, workingDir, cmdLine, env, logfile, opts);
var live = new LiveCapture(m_Core, m_Core.Renderer.Remote == null ? "" : m_Core.Renderer.Remote.Hostname, ret, this);
ShowLiveCapture(live);
return live;
this.BeginInvoke(new Action(() =>
{
if (ret == 0)
{
MessageBox.Show(string.Format("Error launching {0} for capture.\n\nCheck diagnostic log in Help menu for more details.", exe),
"Error kicking capture", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var live = new LiveCapture(m_Core, m_Core.Renderer.Remote == null ? "" : m_Core.Renderer.Remote.Hostname, ret, this);
ShowLiveCapture(live);
callback(live);
}));
}));
th.Start();
// wait a few ms before popping up a progress bar
th.Join(500);
if (th.IsAlive)
{
ProgressPopup modal = new ProgressPopup((ModalCloseCallback)delegate
{
return !th.IsAlive;
}, false);
modal.SetModalText(String.Format("Launching {0}, please wait...", exe));
modal.ShowDialog();
}
}
private LiveCapture OnInjectTrigger(UInt32 PID, EnvironmentModification[] env, string name, CaptureOptions opts)
private void OnInjectTrigger(UInt32 PID, EnvironmentModification[] env, string name, CaptureOptions opts, Dialogs.CaptureDialog.OnConnectionEstablishedMethod callback)
{
if (!PromptCloseLog())
return null;
return;
string logfile = m_Core.TempLogFilename(name);
UInt32 ret = StaticExports.InjectIntoProcess(PID, env, logfile, opts);
if (ret == 0)
Thread th = Helpers.NewThread(new ThreadStart(() =>
{
MessageBox.Show(string.Format("Error injecting into process {0} for capture.\n\nCheck diagnostic log in Help menu for more details.", PID),
"Error kicking capture", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
UInt32 ret = StaticExports.InjectIntoProcess(PID, env, logfile, opts);
var live = new LiveCapture(m_Core, "", ret, this);
ShowLiveCapture(live);
return live;
this.BeginInvoke(new Action(() =>
{
if (ret == 0)
{
MessageBox.Show(string.Format("Error injecting into process {0} for capture.\n\nCheck diagnostic log in Help menu for more details.", PID),
"Error kicking capture", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var live = new LiveCapture(m_Core, m_Core.Renderer.Remote == null ? "" : m_Core.Renderer.Remote.Hostname, ret, this);
ShowLiveCapture(live);
callback(live);
}));
}));
th.Start();
// wait a few ms before popping up a progress bar
th.Join(500);
if (th.IsAlive)
{
ProgressPopup modal = new ProgressPopup((ModalCloseCallback)delegate
{
return !th.IsAlive;
}, false);
modal.SetModalText(String.Format("Injecting into {0}, please wait...", PID));
modal.ShowDialog();
}
}
private void captureLogToolStripMenuItem_Click(object sender, EventArgs e)