File size: 4,850 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | using System.Collections.Generic;
using System.Linq;
namespace Unity.VisualScripting
{
public abstract class UnitPort<TValidOther, TInvalidOther, TExternalConnection> : IUnitPort
where TValidOther : IUnitPort
where TInvalidOther : IUnitPort
where TExternalConnection : IUnitConnection
{
protected UnitPort(string key)
{
Ensure.That(nameof(key)).IsNotNull(key);
this.key = key;
}
public IUnit unit { get; set; }
public string key { get; }
public IGraph graph => unit?.graph;
public IEnumerable<IUnitRelation> relations =>
LinqUtility.Concat<IUnitRelation>(unit.relations.WithSource(this),
unit.relations.WithDestination(this)).Distinct();
public abstract IEnumerable<TExternalConnection> validConnections { get; }
public abstract IEnumerable<InvalidConnection> invalidConnections { get; }
public abstract IEnumerable<TValidOther> validConnectedPorts { get; }
public abstract IEnumerable<TInvalidOther> invalidConnectedPorts { get; }
IEnumerable<IUnitConnection> IUnitPort.validConnections => validConnections.Cast<IUnitConnection>();
public IEnumerable<IUnitConnection> connections => LinqUtility.Concat<IUnitConnection>(validConnections, invalidConnections);
public IEnumerable<IUnitPort> connectedPorts => LinqUtility.Concat<IUnitPort>(validConnectedPorts, invalidConnectedPorts);
public bool hasAnyConnection => hasValidConnection || hasInvalidConnection;
// Allow for more efficient overrides
public virtual bool hasValidConnection => validConnections.Any();
public virtual bool hasInvalidConnection => invalidConnections.Any();
private bool CanConnectTo(IUnitPort port)
{
Ensure.That(nameof(port)).IsNotNull(port);
return unit != null && // We belong to a unit
port.unit != null && // Port belongs to a unit
port.unit != unit && // that is different than the current one
port.unit.graph == unit.graph; // but is on the same graph.
}
public bool CanValidlyConnectTo(IUnitPort port)
{
return CanConnectTo(port) && port is TValidOther && CanConnectToValid((TValidOther)port);
}
public bool CanInvalidlyConnectTo(IUnitPort port)
{
return CanConnectTo(port) && port is TInvalidOther && CanConnectToInvalid((TInvalidOther)port);
}
public void ValidlyConnectTo(IUnitPort port)
{
Ensure.That(nameof(port)).IsNotNull(port);
if (!(port is TValidOther))
{
throw new InvalidConnectionException();
}
ConnectToValid((TValidOther)port);
}
public void InvalidlyConnectTo(IUnitPort port)
{
Ensure.That(nameof(port)).IsNotNull(port);
if (!(port is TInvalidOther))
{
throw new InvalidConnectionException();
}
ConnectToInvalid((TInvalidOther)port);
}
public void Disconnect()
{
while (validConnectedPorts.Any())
{
DisconnectFromValid(validConnectedPorts.First());
}
while (invalidConnectedPorts.Any())
{
DisconnectFromInvalid(invalidConnectedPorts.First());
}
}
public abstract bool CanConnectToValid(TValidOther port);
public bool CanConnectToInvalid(TInvalidOther port)
{
return true;
}
public abstract void ConnectToValid(TValidOther port);
public abstract void ConnectToInvalid(TInvalidOther port);
public abstract void DisconnectFromValid(TValidOther port);
public abstract void DisconnectFromInvalid(TInvalidOther port);
public abstract IUnitPort CompatiblePort(IUnit unit);
protected void ConnectInvalid(IUnitOutputPort source, IUnitInputPort destination)
{
var connection = unit.graph.invalidConnections.SingleOrDefault(c => c.source == source && c.destination == destination);
if (connection != null)
{
return;
}
unit.graph.invalidConnections.Add(new InvalidConnection(source, destination));
}
protected void DisconnectInvalid(IUnitOutputPort source, IUnitInputPort destination)
{
var connection = unit.graph.invalidConnections.SingleOrDefault(c => c.source == source && c.destination == destination);
if (connection == null)
{
return;
}
unit.graph.invalidConnections.Remove(connection);
}
}
}
|