From 58e603bdbe3d1f07bb59ba370ec7f68e6f09e7e0 Mon Sep 17 00:00:00 2001 From: D4VID Date: Fri, 21 Feb 2025 21:13:39 +0100 Subject: [PATCH] Hightlighting cluster perimeter components --- .../src/client/tool/PathHighLighter.cs | 84 ++++++++++++------- .../src/server/ServerPathTracer.cs | 38 ++++++--- .../shared/packets/s2c/AnalyzePathResponse.cs | 1 + 3 files changed, 81 insertions(+), 42 deletions(-) diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighLighter.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighLighter.cs index dbf930c..1e837a6 100644 --- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighLighter.cs +++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighLighter.cs @@ -9,56 +9,72 @@ using LogicWorld.Outlines; namespace CriticalPathAnalyzer.Client.Tool { public class PathHighLighter { private static readonly OutlineData Color = new OutlineData(new Color24(0xff0000)); - + private static readonly OutlineData PerimeterColor = new OutlineData(new Color24(0xffff00)); + private static List _clusters = new List(); + private static List _highlightedComponents = new List(); private static List _highlightedWires = new List(); public static void HighlightWires(AnalyzePathResponse response) { _clusters = response.Clusters; + foreach (ClusterDetails clusterDetails in _clusters) { + HighlightCluster(clusterDetails); + } + IWorldData world = Instances.MainWorld.Data; + + foreach (ComponentAddress componentAddress in response.PerimeterComponents) { + if (!world.Contains(componentAddress)) { + continue; + } + Outliner.Outline(componentAddress, PerimeterColor); + _highlightedComponents.Add(componentAddress); + } + } - foreach (ClusterDetails clusterDetails in _clusters) { - foreach (ComponentAddress address in clusterDetails.ConnectingComponents) { - if (!world.Contains(address)) { - continue; - } + private static void HighlightCluster(ClusterDetails cluster) { + IWorldData world = Instances.MainWorld.Data; - Outliner.Outline(address, Color); + foreach (ComponentAddress address in cluster.ConnectingComponents) { + if (!world.Contains(address)) { + continue; } - foreach (ComponentAddress address in clusterDetails.LinkingComponents) { - if (!world.Contains(address)) { - continue; - } + Outliner.Outline(address, Color); + } - Outliner.Outline(address, Color); + foreach (ComponentAddress address in cluster.LinkingComponents) { + if (!world.Contains(address)) { + continue; } - foreach (PegAddress pegAddress in clusterDetails.Pegs) { - if (!world.Contains(pegAddress.ComponentAddress)) { - continue; - } + Outliner.Outline(address, Color); + } + + foreach (PegAddress pegAddress in cluster.Pegs) { + if (!world.Contains(pegAddress.ComponentAddress)) { + continue; + } + + Outliner.Outline(pegAddress, Color); - Outliner.Outline(pegAddress, Color); + HashSet wires = Instances.MainWorld.Data.LookupPegWires(pegAddress); + if (wires == null) { + continue; + } - HashSet wires = Instances.MainWorld.Data.LookupPegWires(pegAddress); - if (wires == null) { - continue; + foreach (WireAddress wireAddress in wires) { + Wire wire = Instances.MainWorld.Data.Lookup(wireAddress); + if (wire == null) { + return; } - foreach (WireAddress wireAddress in wires) { - Wire wire = Instances.MainWorld.Data.Lookup(wireAddress); - if (wire == null) { - return; - } - - // 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()) { - _highlightedWires.Add(wireAddress); - Outliner.Outline(wireAddress, Color); - } + // 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()) { + _highlightedWires.Add(wireAddress); + Outliner.Outline(wireAddress, Color); } } } @@ -69,6 +85,7 @@ namespace CriticalPathAnalyzer.Client.Tool { CriticalPathAnalyzerClient.LoggerInstance.Warn("Ignoring remove highlighting, clusters is null"); return; } + foreach (ClusterDetails cluster in _clusters) { UnhighlightCluster(cluster); } @@ -76,9 +93,14 @@ namespace CriticalPathAnalyzer.Client.Tool { foreach (WireAddress wireAddress in _highlightedWires) { Outliner.RemoveOutline(wireAddress); } + + foreach (ComponentAddress componentAddress in _highlightedComponents) { + Outliner.RemoveOutline(componentAddress); + } _clusters = null; _highlightedWires.Clear(); + _highlightedComponents.Clear(); } private static void UnhighlightCluster(ClusterDetails cluster) { diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/ServerPathTracer.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/ServerPathTracer.cs index 48bcc44..11c5b24 100644 --- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/ServerPathTracer.cs +++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/ServerPathTracer.cs @@ -54,27 +54,43 @@ namespace CriticalPathAnalyzer.Server { // An input peg, only has a single cluster. // An output peg however can be connected to multiple clusters. // It only makes sense to then select all these clusters as primary cluster. - if (!CollectMainClusters(start, out HashSet primaryClusters)) { + if (!CollectMainClusters(start, out HashSet collectedClusters)) { return false; // Whoops, cannot collect the primary clusters, probably probing an output peg. } + + CriticalPathAnalyzerServer.LoggerInstance.Info("collected main clusters"); // Collect clusters that get powered by the original cluster by fast buffers var collectedDrains = new HashSet(); - foreach (Cluster cluster in primaryClusters) { - CollectClusters(cluster, collectedDrains, GetFollowers); + foreach (Cluster cluster in collectedClusters) { + GetLinkedClusters(cluster, collectedDrains, GetFollowers); } - - foreach (Cluster cluster in primaryClusters) { - collectedDrains.Remove(cluster); + + collectedClusters.UnionWith(collectedDrains); + + CriticalPathAnalyzerServer.LoggerInstance.Info("collected linked clusters"); + + var perimeterComponents = new HashSet(); + foreach (Cluster cluster in collectedClusters) { + foreach (InputPeg inputPeg in cluster.ConnectedInputs) { + if (inputPeg.LogicComponent == null) { + // These are regular pegs, they are not attached to any logic component, skip them + continue; + } + perimeterComponents.Add(inputPeg.LogicComponent.Address); + } } - //Collect information about each cluster: + CriticalPathAnalyzerServer.LoggerInstance.Info("collected perimeter components"); + + // Collect information about each cluster: response = new AnalyzePathResponse() { RequestGuid = requestGuid, - Clusters = new List(), + Clusters = collectedClusters.Select(CollectClusterInformation).ToList(), + PerimeterComponents = perimeterComponents.ToList() }; - response.Clusters.AddRange(primaryClusters.Select(CollectClusterInformation)); - response.Clusters.AddRange(collectedDrains.Select(CollectClusterInformation)); + + CriticalPathAnalyzerServer.LoggerInstance.Info("Trace end"); return true; } @@ -141,7 +157,7 @@ namespace CriticalPathAnalyzer.Server { return true; } - private static void CollectClusters( + private static void GetLinkedClusters( Cluster startingPoint, HashSet collectedClusters, Func> linkedLinkerGetter diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs index 2f58b05..d5bf778 100644 --- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs +++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs @@ -9,6 +9,7 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C { public class AnalyzePathResponse : Packet { [Key(0)] public Guid RequestGuid; [Key(1)] public List Clusters; + [Key(2)] public List PerimeterComponents; } [MessagePackObject]