暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. namespace Unity.VisualScripting
  4. {
  5. public abstract class UnitPort<TValidOther, TInvalidOther, TExternalConnection> : IUnitPort
  6. where TValidOther : IUnitPort
  7. where TInvalidOther : IUnitPort
  8. where TExternalConnection : IUnitConnection
  9. {
  10. protected UnitPort(string key)
  11. {
  12. Ensure.That(nameof(key)).IsNotNull(key);
  13. this.key = key;
  14. }
  15. public IUnit unit { get; set; }
  16. public string key { get; }
  17. public IGraph graph => unit?.graph;
  18. public IEnumerable<IUnitRelation> relations =>
  19. LinqUtility.Concat<IUnitRelation>(unit.relations.WithSource(this),
  20. unit.relations.WithDestination(this)).Distinct();
  21. public abstract IEnumerable<TExternalConnection> validConnections { get; }
  22. public abstract IEnumerable<InvalidConnection> invalidConnections { get; }
  23. public abstract IEnumerable<TValidOther> validConnectedPorts { get; }
  24. public abstract IEnumerable<TInvalidOther> invalidConnectedPorts { get; }
  25. IEnumerable<IUnitConnection> IUnitPort.validConnections => validConnections.Cast<IUnitConnection>();
  26. public IEnumerable<IUnitConnection> connections => LinqUtility.Concat<IUnitConnection>(validConnections, invalidConnections);
  27. public IEnumerable<IUnitPort> connectedPorts => LinqUtility.Concat<IUnitPort>(validConnectedPorts, invalidConnectedPorts);
  28. public bool hasAnyConnection => hasValidConnection || hasInvalidConnection;
  29. // Allow for more efficient overrides
  30. public virtual bool hasValidConnection => validConnections.Any();
  31. public virtual bool hasInvalidConnection => invalidConnections.Any();
  32. private bool CanConnectTo(IUnitPort port)
  33. {
  34. Ensure.That(nameof(port)).IsNotNull(port);
  35. return unit != null && // We belong to a unit
  36. port.unit != null && // Port belongs to a unit
  37. port.unit != unit && // that is different than the current one
  38. port.unit.graph == unit.graph; // but is on the same graph.
  39. }
  40. public bool CanValidlyConnectTo(IUnitPort port)
  41. {
  42. return CanConnectTo(port) && port is TValidOther && CanConnectToValid((TValidOther)port);
  43. }
  44. public bool CanInvalidlyConnectTo(IUnitPort port)
  45. {
  46. return CanConnectTo(port) && port is TInvalidOther && CanConnectToInvalid((TInvalidOther)port);
  47. }
  48. public void ValidlyConnectTo(IUnitPort port)
  49. {
  50. Ensure.That(nameof(port)).IsNotNull(port);
  51. if (!(port is TValidOther))
  52. {
  53. throw new InvalidConnectionException();
  54. }
  55. ConnectToValid((TValidOther)port);
  56. }
  57. public void InvalidlyConnectTo(IUnitPort port)
  58. {
  59. Ensure.That(nameof(port)).IsNotNull(port);
  60. if (!(port is TInvalidOther))
  61. {
  62. throw new InvalidConnectionException();
  63. }
  64. ConnectToInvalid((TInvalidOther)port);
  65. }
  66. public void Disconnect()
  67. {
  68. while (validConnectedPorts.Any())
  69. {
  70. DisconnectFromValid(validConnectedPorts.First());
  71. }
  72. while (invalidConnectedPorts.Any())
  73. {
  74. DisconnectFromInvalid(invalidConnectedPorts.First());
  75. }
  76. }
  77. public abstract bool CanConnectToValid(TValidOther port);
  78. public bool CanConnectToInvalid(TInvalidOther port)
  79. {
  80. return true;
  81. }
  82. public abstract void ConnectToValid(TValidOther port);
  83. public abstract void ConnectToInvalid(TInvalidOther port);
  84. public abstract void DisconnectFromValid(TValidOther port);
  85. public abstract void DisconnectFromInvalid(TInvalidOther port);
  86. public abstract IUnitPort CompatiblePort(IUnit unit);
  87. protected void ConnectInvalid(IUnitOutputPort source, IUnitInputPort destination)
  88. {
  89. var connection = unit.graph.invalidConnections.SingleOrDefault(c => c.source == source && c.destination == destination);
  90. if (connection != null)
  91. {
  92. return;
  93. }
  94. unit.graph.invalidConnections.Add(new InvalidConnection(source, destination));
  95. }
  96. protected void DisconnectInvalid(IUnitOutputPort source, IUnitInputPort destination)
  97. {
  98. var connection = unit.graph.invalidConnections.SingleOrDefault(c => c.source == source && c.destination == destination);
  99. if (connection == null)
  100. {
  101. return;
  102. }
  103. unit.graph.invalidConnections.Remove(connection);
  104. }
  105. }
  106. }