44 lines
2.4 KiB
C#
44 lines
2.4 KiB
C#
namespace PamhagenSysCtrl.Helpers.Pipeline {
|
|
public record struct Path(
|
|
INode Start,
|
|
(IEdge Edge, INode Node)[] Hops
|
|
) {
|
|
public readonly int Bends => Hops.Sum(h => (h.Node is not Valve && h.Node is not PipeJoin ? 1 : 0) + (h.Edge.Start.CenterX != h.Edge.End.CenterX && h.Edge.Start.CenterY != h.Edge.End.CenterY ? 1 : 0));
|
|
public readonly double Length => Hops.Sum(h => Math.Abs(h.Edge.Start.CenterX - h.Edge.End.CenterX) + Math.Abs(h.Edge.Start.CenterY - h.Edge.End.CenterY));
|
|
|
|
public readonly INode End => Hops.Last().Node;
|
|
public readonly IEnumerable<INode> Nodes => [Start, .. Hops.Select(h => h.Node)];
|
|
|
|
public readonly bool Contains(INode node) => Nodes.Any(h => h == node);
|
|
public readonly bool Matches(INode start, INode end) => Matches(start, null, end);
|
|
public readonly bool Matches(INode start, INode? intermediate, INode end) => Start == start && End == end && (intermediate == null || Nodes.Any(n => n == intermediate));
|
|
|
|
public readonly IEnumerable<Pump> Pumps => Nodes.Select(n => n as Pump).Where(p => p != null).Cast<Pump>();
|
|
public readonly IEnumerable<Valve> Valves => Nodes.Select(n => n as Valve).Where(v => v != null).Cast<Valve>();
|
|
|
|
private readonly IEnumerable<ControlledValve> InnerAndBorderValves => Nodes
|
|
.SelectMany(node => PamhagenGraph.TraverseSubgraph(node, (n) => n is ControlledValve || n is ISink || n is Pump))
|
|
.Select(e => e.End as ControlledValve)
|
|
.Where(v => v != null)
|
|
.Cast<ControlledValve>()
|
|
.Distinct();
|
|
public readonly IEnumerable<ControlledValve> InnerValves => Nodes.Select(n => n as ControlledValve).Where(v => v != null).Cast<ControlledValve>();
|
|
public readonly IEnumerable<ControlledValve> BorderValves => InnerAndBorderValves.Except(InnerValves);
|
|
|
|
public readonly bool HasActivePump => Nodes.Any(n => n is Pump p && p.IsActive);
|
|
public readonly bool IsReady => InnerValves.All(v => v.IsOpen && v.WantOpen && v.IsLocked) && BorderValves.All(v => v.IsClosed && !v.WantOpen && v.IsLocked);
|
|
|
|
public readonly void LockValves() {
|
|
foreach (var v in InnerAndBorderValves) {
|
|
v.LockedForPaths.Add(this);
|
|
}
|
|
}
|
|
|
|
public readonly void UnlockValves() {
|
|
foreach (var v in InnerAndBorderValves) {
|
|
v.LockedForPaths.Remove(this);
|
|
}
|
|
}
|
|
}
|
|
}
|