149 lines
4.7 KiB
C#
149 lines
4.7 KiB
C#
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|