Code/Core/Wire.cs
namespace Nodebox;
public sealed class Wire : GraphElement, IMeta {
private Node _source = null;
[JsonIgnore]
public Node Source {
get => _source;
set {
if (_source == value) {
return;
}
Disconnect();
_source = value;
Connect();
}
}
private PinIndex _sourceIndex = PinIndex.Invalid;
[JsonIgnore]
public PinIndex SourceIndex {
get => _sourceIndex;
set {
if (_sourceIndex == value) {
return;
}
Disconnect();
_sourceIndex = value;
Connect();
}
}
private Node _destination = null;
[JsonIgnore]
public Node Destination {
get => _destination;
set {
if (_destination == value) {
return;
}
Disconnect();
_destination = value;
Connect();
}
}
private PinIndex _destinationIndex = PinIndex.Invalid;
[JsonIgnore]
public PinIndex DestinationIndex {
get => _destinationIndex;
set {
if (_destinationIndex == value) {
return;
}
Disconnect();
_destinationIndex = value;
Connect();
}
}
[JsonIgnore]
public Pin SourcePin => _source.OutputPins[_sourceIndex];
[JsonIgnore]
public Pin DestinationPin => _destination.InputPins[_destinationIndex];
[JsonIgnore]
public Type SourceType => SourcePin.Type;
[JsonIgnore]
public Type DestinationType => DestinationPin.Type;
[JsonIgnore]
public override Type DirectoryType => typeof(Wire);
public Dictionary<string, object> Meta { get; private set; } = [];
private bool _valid = false;
[JsonIgnore]
public override bool IsValid => _valid && base.IsValid && _source.IsValid && _destination.IsValid;
public Wire() : base() { }
public Wire(Node source, PinIndex sourceIndex, Node destination, PinIndex destinationIndex) : this() {
Check(source, sourceIndex, destination, destinationIndex);
_source = source;
_sourceIndex = sourceIndex;
_destination = destination;
_destinationIndex = destinationIndex;
Connect();
}
public static void Check(Node source, PinIndex sourceIndex, Node destination, PinIndex destinationIndex) {
Assert.IsValid(source);
Assert.IsValid(destination);
ArgumentNullOrInvalidException.ThrowIfNullOrNotValid(source, nameof(source));
ArgumentNullOrInvalidException.ThrowIfNullOrNotValid(destination, nameof(destination));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(sourceIndex, source.OutputPins.Count, nameof(sourceIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(destinationIndex, destination.InputPins.Count, nameof(destinationIndex));
}
private void CheckSelf() => Check(_source, _sourceIndex, _destination, _destinationIndex);
private void Connect() {
CheckSelf();
// var sourcePin = _source.outputPins[_sourceIndex];
// var destinationPin = _destination.inputPins[_sourceIndex];
_source.AddOutputWire(_sourceIndex, this);
_destination.AddInputWire(_destinationIndex, this);
_valid = true;
}
private void Disconnect() {
_source?.RemoveOutputWire(_sourceIndex, this);
_destination?.RemoveInputWire(_destinationIndex, this);
}
protected override void Term() {
Disconnect();
Meta.Clear();
base.Term();
_valid = false;
}
public override string ToString() {
return $"{DisplayInfo.ForGenericType(Source.GetType()).Name}[{SourceIndex}] -> {DisplayInfo.ForGenericType(Destination.GetType()).Name}[{DestinationIndex}]";
}
~Wire() {
Destroy();
}
}