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