Begin searching nodes

master
D4VID 7 months ago
parent ccc75c9f1e
commit df5cc73e90

@ -88,7 +88,6 @@ namespace CriticalPathAnalyzer.Client.Tool {
public static void RemoveHighLighting() {
if (_clusters == null) {
CriticalPathAnalyzerClient.LoggerInstance.Warn("Ignoring remove highlighting, clusters is null");
return;
}

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using CriticalPathAnalyzer.Server.Network;
using CriticalPathAnalyzer.Server.Tool;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Server.Injectors;
using EccsLogicWorldAPI.Shared.PacketWrapper;

@ -0,0 +1,12 @@
using System.Collections.Generic;
using LogicWorld.Server.Circuitry;
namespace CriticalPathAnalyzer.Server.Tool {
public class ClusterNode {
public int Index; // "identifier"
public List<Cluster> Clusters; // bidirectionally connected clusters without delay
public int Time; // what point in time has been this cluster last updated
public Dictionary<int, int> NextNodes; // next cluster StateID / delay between them
public int? PrevNodeStateId; // the last cluster that updated this one
}
}

@ -9,7 +9,7 @@ using LogicAPI.Server.Components;
using LogicAPI.Services;
using LogicWorld.Server.Circuitry;
namespace CriticalPathAnalyzer.Server {
namespace CriticalPathAnalyzer.Server.Tool {
public class ServerPathTracer {
// Reflection/Delegate access helpers:
private static readonly Func<InputPeg, Cluster> GetCluster;
@ -44,8 +44,6 @@ namespace CriticalPathAnalyzer.Server {
) {
response = null;
var clusterTime = new Dictionary<Cluster, int>();
CriticalPathAnalyzerServer.LoggerInstance.Info("Trace start");
// Validate, that the peg is actually existing:
@ -54,23 +52,41 @@ namespace CriticalPathAnalyzer.Server {
return false;
}
var clusterNodes = new List<ClusterNode>();
var nodeQueue = new Queue<ClusterNode>();
// 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.
var collectedClusters = new HashSet<Cluster>();
CollectMainClusters(start, collectedClusters);
CriticalPathAnalyzerServer.LoggerInstance.Info("collected main clusters");
CriticalPathAnalyzerServer.LoggerInstance.Info($"collected {collectedClusters.Count} main clusters");
// Collect clusters that get powered by the original cluster by fast buffers
var collectedDrains = new HashSet<Cluster>();
// Collect clusters that get powered by the original cluster using relays or fast buffers
var oneWayConnectedClusters = new HashSet<Cluster>();
var twoWayConnectedClusters = new HashSet<Cluster>();
foreach (Cluster cluster in collectedClusters) {
GetLinkedClusters(cluster, collectedDrains, GetFollowers);
GetLinkedClusters(cluster, oneWayConnectedClusters, twoWayConnectedClusters, GetFollowers);
}
collectedClusters.UnionWith(collectedDrains);
CriticalPathAnalyzerServer.LoggerInstance.Info(
$"collected {oneWayConnectedClusters.Count} one way linked clusters");
CriticalPathAnalyzerServer.LoggerInstance.Info(
$"collected {twoWayConnectedClusters.Count} two way linked clusters");
// collectedClusters.UnionWith(oneWayConnectedClusters);
collectedClusters.UnionWith(twoWayConnectedClusters);
CriticalPathAnalyzerServer.LoggerInstance.Info("collected linked clusters");
CriticalPathAnalyzerServer.LoggerInstance.Info($"union {collectedClusters.Count} clusters");
clusterNodes.Add(new ClusterNode() {
Index = clusterNodes.Count,
Clusters = collectedClusters.ToList(),
Time = 0,
PrevNodeStateId = null,
NextNodes = new Dictionary<int, int>(),
});
var perimeterComponents = new HashSet<ComponentAddress>();
var collectedNextClusters = new HashSet<Cluster>();
@ -165,7 +181,8 @@ namespace CriticalPathAnalyzer.Server {
private static void GetLinkedClusters(
Cluster startingPoint,
HashSet<Cluster> collectedClusters,
HashSet<Cluster> oneWayConnectedClusters,
HashSet<Cluster> twoWayConnectedClusters,
Func<ClusterLinker, List<ClusterLinker>> linkedLinkerGetter
) {
var clustersToProcess = new Queue<ClusterLinker>();
@ -175,17 +192,26 @@ namespace CriticalPathAnalyzer.Server {
clustersToProcess.Enqueue(startingLinker);
// While the starting cluster is no source, the algorithm needs to skip it when encountered.
// collectedClusters.Add(startingPoint);
while (clustersToProcess.TryDequeue(out ClusterLinker linkerToCheck)) {
List<ClusterLinker> listOfLinkedLinkers = linkedLinkerGetter(linkerToCheck); // Is never null.
foreach (ClusterLinker linkedLinker in listOfLinkedLinkers) {
Cluster clusterOfLinkedLinker = linkedLinker.ClusterBeingLinked; // Should never be null.
if (collectedClusters.Add(clusterOfLinkedLinker)) {
// Element was not yet present in the array, so keep looking into it!
clustersToProcess.Enqueue(linkedLinker);
List<ClusterLinker> listOfBackLinkers = linkedLinkerGetter(linkedLinker); // Is never null.
if (listOfBackLinkers.Contains(linkerToCheck)) {
// bidirectional - a relay
if (twoWayConnectedClusters.Add(clusterOfLinkedLinker)) {
// Element was not yet present in the array, so keep looking into it!
clustersToProcess.Enqueue(linkedLinker);
}
} else {
// unidirectional - a fast buffer
oneWayConnectedClusters.Add(clusterOfLinkedLinker);
// stop propagation
}
}
}
twoWayConnectedClusters.Remove(startingPoint);
}
private static ClusterDetails CollectClusterInformation(Cluster cluster) {

@ -16,7 +16,7 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[MessagePackObject]
public sealed class ClusterDetails {
[Key(0)] public List<PegAddress> Pegs;
[Key(1)] public List<ComponentAddress> ConnectingComponents;
[Key(2)] public List<ComponentAddress> LinkingComponents;
[Key(1)] public List<ComponentAddress> ConnectingComponents; // Sockets
[Key(2)] public List<ComponentAddress> LinkingComponents; // Relays, fast buffers
}
}
Loading…
Cancel
Save