A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5namespace Unity.VisualScripting
6{
7 public sealed class ControlOutput : UnitPort<ControlInput, IUnitInputPort, ControlConnection>, IUnitControlPort, IUnitOutputPort
8 {
9 public ControlOutput(string key) : base(key) { }
10
11 public override IEnumerable<ControlConnection> validConnections => unit?.graph?.controlConnections.WithSource(this) ?? Enumerable.Empty<ControlConnection>();
12
13 public override IEnumerable<InvalidConnection> invalidConnections => unit?.graph?.invalidConnections.WithSource(this) ?? Enumerable.Empty<InvalidConnection>();
14
15 public override IEnumerable<ControlInput> validConnectedPorts => validConnections.Select(c => c.destination);
16
17 public override IEnumerable<IUnitInputPort> invalidConnectedPorts => invalidConnections.Select(c => c.destination);
18
19 public bool isPredictable
20 {
21 get
22 {
23 using (var recursion = Recursion.New(1))
24 {
25 return IsPredictable(recursion);
26 }
27 }
28 }
29
30 public bool IsPredictable(Recursion recursion)
31 {
32 if (unit.isControlRoot)
33 {
34 return true;
35 }
36
37 if (!recursion?.TryEnter(this) ?? false)
38 {
39 return false;
40 }
41
42 var isPredictable = unit.relations.WithDestination(this).Where(r => r.source is ControlInput).All(r => ((ControlInput)r.source).IsPredictable(recursion));
43
44 recursion?.Exit(this);
45
46 return isPredictable;
47 }
48
49 public bool couldBeEntered
50 {
51 get
52 {
53 if (!isPredictable)
54 {
55 throw new NotSupportedException();
56 }
57
58 if (unit.isControlRoot)
59 {
60 return true;
61 }
62
63 return unit.relations.WithDestination(this).Where(r => r.source is ControlInput).Any(r => ((ControlInput)r.source).couldBeEntered);
64 }
65 }
66
67 public ControlConnection connection => unit.graph?.controlConnections.SingleOrDefaultWithSource(this);
68
69 public override bool hasValidConnection => connection != null;
70
71 public override bool CanConnectToValid(ControlInput port)
72 {
73 return true;
74 }
75
76 public override void ConnectToValid(ControlInput port)
77 {
78 var source = this;
79 var destination = port;
80
81 source.Disconnect();
82
83 unit.graph.controlConnections.Add(new ControlConnection(source, destination));
84 }
85
86 public override void ConnectToInvalid(IUnitInputPort port)
87 {
88 ConnectInvalid(this, port);
89 }
90
91 public override void DisconnectFromValid(ControlInput port)
92 {
93 var connection = validConnections.SingleOrDefault(c => c.destination == port);
94
95 if (connection != null)
96 {
97 unit.graph.controlConnections.Remove(connection);
98 }
99 }
100
101 public override void DisconnectFromInvalid(IUnitInputPort port)
102 {
103 DisconnectInvalid(this, port);
104 }
105
106 public override IUnitPort CompatiblePort(IUnit unit)
107 {
108 if (unit == this.unit) return null;
109
110 return unit.controlInputs.FirstOrDefault();
111 }
112 }
113}