mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
When executing python scripts temporarily catch exceptions in renderer
* Errors like syntax and runtime errors in python are thrown as exceptions. So for when we invoke onto the renderer thread to do some work, we need to be able to catch those exceptions otherwise the whole program dies. So over the execute, temporarily switch the thread into a catching-exception mode, which then gets rethrown on the invoker's thread. * Note that BeginInvoke shouldn't be used by python since the callback might happen after the execution has finished (there's no way to wait at the moment).
This commit is contained in:
@@ -52,6 +52,7 @@ namespace renderdocui.Code
|
||||
|
||||
public InvokeMethod method;
|
||||
volatile public bool processed;
|
||||
public Exception ex = null;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
@@ -113,6 +114,14 @@ namespace renderdocui.Code
|
||||
|
||||
public float LoadProgress;
|
||||
|
||||
[ThreadStatic]
|
||||
private bool CatchExceptions = false;
|
||||
|
||||
public void SetExceptionCatching(bool catching)
|
||||
{
|
||||
CatchExceptions = catching;
|
||||
}
|
||||
|
||||
public void BeginInvoke(InvokeMethod m)
|
||||
{
|
||||
InvokeHandle cmd = new InvokeHandle(m);
|
||||
@@ -127,6 +136,9 @@ namespace renderdocui.Code
|
||||
PushInvoke(cmd);
|
||||
|
||||
while (!cmd.processed) ;
|
||||
|
||||
if (cmd.ex != null)
|
||||
throw cmd.ex;
|
||||
}
|
||||
|
||||
private void PushInvoke(InvokeHandle cmd)
|
||||
@@ -204,7 +216,23 @@ namespace renderdocui.Code
|
||||
foreach (var cmd in queue)
|
||||
{
|
||||
if (cmd.method != null)
|
||||
cmd.method(renderer);
|
||||
{
|
||||
if (CatchExceptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmd.method(renderer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
cmd.ex = ex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.method(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
cmd.processed = true;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,9 @@ namespace renderdocui.Windows.Dialogs
|
||||
|
||||
try
|
||||
{
|
||||
m_Core.Renderer.SetExceptionCatching(true);
|
||||
dynamic ret = engine.CreateScriptSourceFromString(script).Execute(scope);
|
||||
m_Core.Renderer.SetExceptionCatching(false);
|
||||
if (ret != null)
|
||||
{
|
||||
stdoutwriter.Write(ret.ToString() + Environment.NewLine);
|
||||
@@ -137,6 +139,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_Core.Renderer.SetExceptionCatching(false);
|
||||
|
||||
// IronPython throws so many exceptions, we don't want to kill the application
|
||||
// so we just swallow Exception to cover all the bases
|
||||
string exstr = engine.GetService<ExceptionOperations>().FormatException(ex);
|
||||
|
||||
Reference in New Issue
Block a user