File size: 2,882 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | using System;
namespace Unity.VisualScripting
{
/// <summary>
/// Handles an exception if it occurs.
/// </summary>
[UnitCategory("Control")]
[UnitOrder(17)]
[UnitFooterPorts(ControlOutputs = true)]
public sealed class TryCatch : Unit
{
/// <summary>
/// The entry point for the try-catch block.
/// </summary>
[DoNotSerialize]
[PortLabelHidden]
public ControlInput enter { get; private set; }
/// <summary>
/// The action to attempt.
/// </summary>
[DoNotSerialize]
public ControlOutput @try { get; private set; }
/// <summary>
/// The action to execute if an exception is thrown.
/// </summary>
[DoNotSerialize]
public ControlOutput @catch { get; private set; }
/// <summary>
/// The action to execute afterwards, regardless of whether there was an exception.
/// </summary>
[DoNotSerialize]
public ControlOutput @finally { get; private set; }
/// <summary>
/// The exception that was thrown in the try block.
/// </summary>
[DoNotSerialize]
public ValueOutput exception { get; private set; }
[Serialize]
[Inspectable, UnitHeaderInspectable]
[TypeFilter(typeof(Exception), Matching = TypesMatching.AssignableToAll)]
[TypeSet(TypeSet.SettingsAssembliesTypes)]
public Type exceptionType { get; set; } = typeof(Exception);
public override bool canDefine => exceptionType != null && typeof(Exception).IsAssignableFrom(exceptionType);
protected override void Definition()
{
enter = ControlInput(nameof(enter), Enter);
@try = ControlOutput(nameof(@try));
@catch = ControlOutput(nameof(@catch));
@finally = ControlOutput(nameof(@finally));
exception = ValueOutput(exceptionType, nameof(exception));
Assignment(enter, exception);
Succession(enter, @try);
Succession(enter, @catch);
Succession(enter, @finally);
}
public ControlOutput Enter(Flow flow)
{
if (flow.isCoroutine)
{
throw new NotSupportedException("Coroutines cannot catch exceptions.");
}
try
{
flow.Invoke(@try);
}
catch (Exception ex)
{
if (exceptionType.IsInstanceOfType(ex))
{
flow.SetValue(exception, ex);
flow.Invoke(@catch);
}
else
{
throw;
}
}
finally
{
flow.Invoke(@finally);
}
return null;
}
}
}
|