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}