Find neighbouring clusters

master
D4VID 7 months ago
parent 58e603bdbe
commit ccc75c9f1e

@ -9,6 +9,7 @@ using LogicWorld.Outlines;
namespace CriticalPathAnalyzer.Client.Tool { namespace CriticalPathAnalyzer.Client.Tool {
public class PathHighLighter { public class PathHighLighter {
private static readonly OutlineData Color = new OutlineData(new Color24(0xff0000)); private static readonly OutlineData Color = new OutlineData(new Color24(0xff0000));
private static readonly OutlineData NextColor = new OutlineData(new Color24(0xff00ff));
private static readonly OutlineData PerimeterColor = new OutlineData(new Color24(0xffff00)); private static readonly OutlineData PerimeterColor = new OutlineData(new Color24(0xffff00));
private static List<ClusterDetails> _clusters = new List<ClusterDetails>(); private static List<ClusterDetails> _clusters = new List<ClusterDetails>();
@ -19,7 +20,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
_clusters = response.Clusters; _clusters = response.Clusters;
foreach (ClusterDetails clusterDetails in _clusters) { foreach (ClusterDetails clusterDetails in _clusters) {
HighlightCluster(clusterDetails); HighlightCluster(clusterDetails, Color);
} }
IWorldData world = Instances.MainWorld.Data; IWorldData world = Instances.MainWorld.Data;
@ -32,9 +33,14 @@ namespace CriticalPathAnalyzer.Client.Tool {
Outliner.Outline(componentAddress, PerimeterColor); Outliner.Outline(componentAddress, PerimeterColor);
_highlightedComponents.Add(componentAddress); _highlightedComponents.Add(componentAddress);
} }
_clusters.AddRange(response.NextClusters); // add to the collection to unhighlight
foreach (ClusterDetails clusterDetails in response.NextClusters) {
HighlightCluster(clusterDetails, NextColor);
}
} }
private static void HighlightCluster(ClusterDetails cluster) { private static void HighlightCluster(ClusterDetails cluster, OutlineData outline) {
IWorldData world = Instances.MainWorld.Data; IWorldData world = Instances.MainWorld.Data;
foreach (ComponentAddress address in cluster.ConnectingComponents) { foreach (ComponentAddress address in cluster.ConnectingComponents) {
@ -42,7 +48,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
continue; continue;
} }
Outliner.Outline(address, Color); Outliner.Outline(address, outline);
} }
foreach (ComponentAddress address in cluster.LinkingComponents) { foreach (ComponentAddress address in cluster.LinkingComponents) {
@ -50,7 +56,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
continue; continue;
} }
Outliner.Outline(address, Color); Outliner.Outline(address, outline);
} }
foreach (PegAddress pegAddress in cluster.Pegs) { foreach (PegAddress pegAddress in cluster.Pegs) {
@ -58,7 +64,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
continue; continue;
} }
Outliner.Outline(pegAddress, Color); Outliner.Outline(pegAddress, outline);
HashSet<WireAddress> wires = Instances.MainWorld.Data.LookupPegWires(pegAddress); HashSet<WireAddress> wires = Instances.MainWorld.Data.LookupPegWires(pegAddress);
if (wires == null) { if (wires == null) {
@ -74,7 +80,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
// We do not collect wires from output pegs. So if the first is an output peg, the other side must be an input -> collect. // We do not collect wires from output pegs. So if the first is an output peg, the other side must be an input -> collect.
if (wire.Point1 == pegAddress || !wire.Point1.IsInputAddress()) { if (wire.Point1 == pegAddress || !wire.Point1.IsInputAddress()) {
_highlightedWires.Add(wireAddress); _highlightedWires.Add(wireAddress);
Outliner.Outline(wireAddress, Color); Outliner.Outline(wireAddress, outline);
} }
} }
} }

@ -5,6 +5,7 @@ using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Server; using EccsLogicWorldAPI.Server;
using EccsLogicWorldAPI.Shared.AccessHelper; using EccsLogicWorldAPI.Shared.AccessHelper;
using LogicAPI.Data; using LogicAPI.Data;
using LogicAPI.Server.Components;
using LogicAPI.Services; using LogicAPI.Services;
using LogicWorld.Server.Circuitry; using LogicWorld.Server.Circuitry;
@ -43,6 +44,8 @@ namespace CriticalPathAnalyzer.Server {
) { ) {
response = null; response = null;
var clusterTime = new Dictionary<Cluster, int>();
CriticalPathAnalyzerServer.LoggerInstance.Info("Trace start"); CriticalPathAnalyzerServer.LoggerInstance.Info("Trace start");
// Validate, that the peg is actually existing: // Validate, that the peg is actually existing:
@ -54,10 +57,9 @@ namespace CriticalPathAnalyzer.Server {
// An input peg, only has a single cluster. // An input peg, only has a single cluster.
// An output peg however can be connected to multiple clusters. // An output peg however can be connected to multiple clusters.
// It only makes sense to then select all these clusters as primary cluster. // It only makes sense to then select all these clusters as primary cluster.
if (!CollectMainClusters(start, out HashSet<Cluster> collectedClusters)) { var collectedClusters = new HashSet<Cluster>();
return false; // Whoops, cannot collect the primary clusters, probably probing an output peg. CollectMainClusters(start, collectedClusters);
}
CriticalPathAnalyzerServer.LoggerInstance.Info("collected main clusters"); CriticalPathAnalyzerServer.LoggerInstance.Info("collected main clusters");
// Collect clusters that get powered by the original cluster by fast buffers // Collect clusters that get powered by the original cluster by fast buffers
@ -65,31 +67,38 @@ namespace CriticalPathAnalyzer.Server {
foreach (Cluster cluster in collectedClusters) { foreach (Cluster cluster in collectedClusters) {
GetLinkedClusters(cluster, collectedDrains, GetFollowers); GetLinkedClusters(cluster, collectedDrains, GetFollowers);
} }
collectedClusters.UnionWith(collectedDrains); collectedClusters.UnionWith(collectedDrains);
CriticalPathAnalyzerServer.LoggerInstance.Info("collected linked clusters"); CriticalPathAnalyzerServer.LoggerInstance.Info("collected linked clusters");
var perimeterComponents = new HashSet<ComponentAddress>(); var perimeterComponents = new HashSet<ComponentAddress>();
var collectedNextClusters = new HashSet<Cluster>();
foreach (Cluster cluster in collectedClusters) { foreach (Cluster cluster in collectedClusters) {
foreach (InputPeg inputPeg in cluster.ConnectedInputs) { foreach (InputPeg inputPeg in cluster.ConnectedInputs) {
if (inputPeg.LogicComponent == null) { if (inputPeg.LogicComponent == null) {
// These are regular pegs, they are not attached to any logic component, skip them // These are regular pegs, they are not attached to any logic component, skip them
continue; continue;
} }
perimeterComponents.Add(inputPeg.LogicComponent.Address); perimeterComponents.Add(inputPeg.LogicComponent.Address);
foreach (IOutputPeg outputPeg in inputPeg.LogicComponent.Outputs) {
CollectMainClusters(outputPeg.Address, collectedNextClusters);
}
} }
} }
CriticalPathAnalyzerServer.LoggerInstance.Info("collected perimeter components"); CriticalPathAnalyzerServer.LoggerInstance.Info("collected perimeter components");
// Collect information about each cluster: // Collect information about each cluster:
response = new AnalyzePathResponse() { response = new AnalyzePathResponse() {
RequestGuid = requestGuid, RequestGuid = requestGuid,
Clusters = collectedClusters.Select(CollectClusterInformation).ToList(), Clusters = collectedClusters.Select(CollectClusterInformation).ToList(),
PerimeterComponents = perimeterComponents.ToList() PerimeterComponents = perimeterComponents.ToList(),
NextClusters = collectedNextClusters.Select(CollectClusterInformation).ToList(),
}; };
CriticalPathAnalyzerServer.LoggerInstance.Info("Trace end"); CriticalPathAnalyzerServer.LoggerInstance.Info("Trace end");
return true; return true;
@ -128,14 +137,13 @@ namespace CriticalPathAnalyzer.Server {
return linker != null; return linker != null;
} }
private static bool CollectMainClusters(PegAddress pegAddress, out HashSet<Cluster> primaryClusters) { private static void CollectMainClusters(PegAddress pegAddress, HashSet<Cluster> primaryClusters) {
primaryClusters = new HashSet<Cluster>();
if (pegAddress.IsInputAddress(out InputAddress inputAddress)) { if (pegAddress.IsInputAddress(out InputAddress inputAddress)) {
primaryClusters.Add(GetClusterAt(inputAddress)); primaryClusters.Add(GetClusterAt(inputAddress));
} else { } else {
HashSet<WireAddress> wires = World.LookupPegWires(pegAddress); HashSet<WireAddress> wires = World.LookupPegWires(pegAddress);
if (wires == null) { if (wires == null) {
return true; return;
} }
foreach (WireAddress wireAddress in wires) { foreach (WireAddress wireAddress in wires) {
@ -146,15 +154,13 @@ namespace CriticalPathAnalyzer.Server {
} }
PegAddress otherSide = wire.Point1 == pegAddress ? wire.Point2 : wire.Point1; PegAddress otherSide = wire.Point1 == pegAddress ? wire.Point2 : wire.Point1;
if (!otherSide.IsInputAddress(out var otherSideInputAddress)) { if (!otherSide.IsInputAddress(out InputAddress otherSideInputAddress)) {
continue; //Not supported, this wire would be invalid anyway. continue; // Not supported, this wire would be invalid anyway.
} }
primaryClusters.Add(GetClusterAt(otherSideInputAddress)); primaryClusters.Add(GetClusterAt(otherSideInputAddress));
} }
} }
return true;
} }
private static void GetLinkedClusters( private static void GetLinkedClusters(

@ -10,6 +10,7 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[Key(0)] public Guid RequestGuid; [Key(0)] public Guid RequestGuid;
[Key(1)] public List<ClusterDetails> Clusters; [Key(1)] public List<ClusterDetails> Clusters;
[Key(2)] public List<ComponentAddress> PerimeterComponents; [Key(2)] public List<ComponentAddress> PerimeterComponents;
[Key(3)] public List<ClusterDetails> NextClusters;
} }
[MessagePackObject] [MessagePackObject]

Loading…
Cancel
Save