Got searching with some colors

master
D4VID 7 months ago
parent df5cc73e90
commit 79def5270b

@ -23,26 +23,28 @@ namespace CriticalPathAnalyzer.Client.Tool {
HighlightCluster(clusterDetails, Color);
}
IWorldData world = Instances.MainWorld.Data;
foreach (ComponentAddress componentAddress in response.PerimeterComponents) {
if (!world.Contains(componentAddress)) {
continue;
}
Outliner.Outline(componentAddress, PerimeterColor);
_highlightedComponents.Add(componentAddress);
}
_clusters.AddRange(response.NextClusters); // add to the collection to unhighlight
foreach (ClusterDetails clusterDetails in response.NextClusters) {
HighlightCluster(clusterDetails, NextColor);
}
// IWorldData world = Instances.MainWorld.Data;
// foreach (ComponentAddress componentAddress in response.PerimeterComponents) {
// if (!world.Contains(componentAddress)) {
// continue;
// }
//
// Outliner.Outline(componentAddress, PerimeterColor);
// _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, OutlineData outline) {
private static void HighlightCluster(ClusterDetails cluster, OutlineData outlineOld) {
IWorldData world = Instances.MainWorld.Data;
var outline = new OutlineData(new Color24(cluster.Color));
foreach (ComponentAddress address in cluster.ConnectingComponents) {
if (!world.Contains(address)) {
continue;

@ -4,9 +4,11 @@ using System.Linq;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Server;
using EccsLogicWorldAPI.Shared.AccessHelper;
using JimmysUnityUtilities;
using LogicAPI.Data;
using LogicAPI.Server.Components;
using LogicAPI.Services;
using LogicLog;
using LogicWorld.Server.Circuitry;
namespace CriticalPathAnalyzer.Server.Tool {
@ -42,18 +44,20 @@ namespace CriticalPathAnalyzer.Server.Tool {
PegAddress end,
out AnalyzePathResponse response
) {
ILogicLogger logger = CriticalPathAnalyzerServer.LoggerInstance;
response = null;
CriticalPathAnalyzerServer.LoggerInstance.Info("Trace start");
logger.Info("Trace start");
// Validate, that the peg is actually existing:
if (!PegExists(start) || !PegExists(end)) {
CriticalPathAnalyzerServer.LoggerInstance.Error("Peg not found");
logger.Error("Peg not found");
return false;
}
var clusterNodes = new List<ClusterNode>();
var nodeQueue = new Queue<ClusterNode>();
var clusterToNodeMapping = new Dictionary<Cluster, int>(); // Cluster / index of node
var queue = new Queue<(Cluster, int)>();
// An input peg, only has a single cluster.
// An output peg however can be connected to multiple clusters.
@ -61,61 +65,95 @@ namespace CriticalPathAnalyzer.Server.Tool {
var collectedClusters = new HashSet<Cluster>();
CollectMainClusters(start, collectedClusters);
CriticalPathAnalyzerServer.LoggerInstance.Info($"collected {collectedClusters.Count} main clusters");
// 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, oneWayConnectedClusters, twoWayConnectedClusters, GetFollowers);
queue.Enqueue((cluster, 0));
}
CriticalPathAnalyzerServer.LoggerInstance.Info(
$"collected {oneWayConnectedClusters.Count} one way linked clusters");
CriticalPathAnalyzerServer.LoggerInstance.Info(
$"collected {twoWayConnectedClusters.Count} two way linked clusters");
logger.Info($"collected {collectedClusters.Count} main clusters");
// collectedClusters.UnionWith(oneWayConnectedClusters);
collectedClusters.UnionWith(twoWayConnectedClusters);
int iters = 0;
while (queue.TryDequeue(out (Cluster, int) item)) {
iters++;
if (iters > 100000) {
logger.Error("Infinite iterations");
break;
}
CriticalPathAnalyzerServer.LoggerInstance.Info($"union {collectedClusters.Count} clusters");
(Cluster cluster, int time) = item;
clusterNodes.Add(new ClusterNode() {
Index = clusterNodes.Count,
Clusters = collectedClusters.ToList(),
Time = 0,
PrevNodeStateId = null,
NextNodes = new Dictionary<int, int>(),
});
logger.Warn(">> cluster iter <<");
var perimeterComponents = new HashSet<ComponentAddress>();
var collectedNextClusters = new HashSet<Cluster>();
foreach (Cluster cluster in collectedClusters) {
if (clusterToNodeMapping.ContainsKey(cluster)) {
logger.Info("already mapped, continuing");
continue;
}
// Collect clusters that get powered by the original cluster using relays or fast buffers
// var nextClusters = new HashSet<Cluster>();
// var twoWayConnectedClusters = new HashSet<Cluster>();
//
// GetLinkedClusters(cluster, nextClusters, twoWayConnectedClusters, GetFollowers);
// logger.Info($"collected {nextClusters.Count} one way linked clusters");
// logger.Info($"collected {twoWayConnectedClusters.Count} two way linked clusters");
int index = clusterNodes.Count;
// foreach (Cluster connectedCluster in twoWayConnectedClusters) {
// if (!clusterToNodeMapping.TryAdd(connectedCluster, index)) {
// // already been here
// logger.Error("Adding already mapped cluster");
// break;
// }
// }
// foreach (Cluster connectedCluster in nextClusters) {
// var nextClusters = new HashSet<Cluster>();
// var twoWayConnectedClusters = new HashSet<Cluster>();
// GetLinkedClusters(connectedCluster, nextClusters, twoWayConnectedClusters, GetFollowers);
// }
clusterToNodeMapping.Add(cluster, index);
clusterNodes.Add(new ClusterNode() {
Index = index,
Clusters = new List<Cluster>() {cluster},
Time = index,
PrevNodeStateId = null,
NextNodes = new Dictionary<int, int>(),
});
// var perimeterComponents = new HashSet<ComponentAddress>();
var collectedNextClusters = new HashSet<Cluster>();
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);
// perimeterComponents.Add(inputPeg.LogicComponent.Address);
foreach (IOutputPeg outputPeg in inputPeg.LogicComponent.Outputs) {
CollectMainClusters(outputPeg.Address, collectedNextClusters);
}
}
}
CriticalPathAnalyzerServer.LoggerInstance.Info("collected perimeter components");
foreach (Cluster nextCluster in collectedNextClusters) {
queue.Enqueue((nextCluster, time + 1));
}
logger.Info("collected perimeter components");
}
// Collect information about each cluster:
response = new AnalyzePathResponse() {
RequestGuid = requestGuid,
Clusters = collectedClusters.Select(CollectClusterInformation).ToList(),
PerimeterComponents = perimeterComponents.ToList(),
NextClusters = collectedNextClusters.Select(CollectClusterInformation).ToList(),
Clusters = clusterNodes.SelectMany(node => node.Clusters.Select(cluster => CollectClusterInformation(cluster, node.Time))).ToList(),
// PerimeterComponents = perimeterComponents.ToList(),
// NextClusters = collectedNextClusters.Select(CollectClusterInformation).ToList(),
};
CriticalPathAnalyzerServer.LoggerInstance.Info("Trace end");
logger.Info("Trace end");
return true;
}
@ -191,6 +229,7 @@ namespace CriticalPathAnalyzer.Server.Tool {
}
clustersToProcess.Enqueue(startingLinker);
twoWayConnectedClusters.Add(startingPoint);
// While the starting cluster is no source, the algorithm needs to skip it when encountered.
while (clustersToProcess.TryDequeue(out ClusterLinker linkerToCheck)) {
List<ClusterLinker> listOfLinkedLinkers = linkedLinkerGetter(linkerToCheck); // Is never null.
@ -199,6 +238,7 @@ namespace CriticalPathAnalyzer.Server.Tool {
List<ClusterLinker> listOfBackLinkers = linkedLinkerGetter(linkedLinker); // Is never null.
if (listOfBackLinkers.Contains(linkerToCheck)) {
// bidirectional - a relay
// TODO: will not find a relay connection if the relay is turned off
if (twoWayConnectedClusters.Add(clusterOfLinkedLinker)) {
// Element was not yet present in the array, so keep looking into it!
clustersToProcess.Enqueue(linkedLinker);
@ -214,11 +254,12 @@ namespace CriticalPathAnalyzer.Server.Tool {
twoWayConnectedClusters.Remove(startingPoint);
}
private static ClusterDetails CollectClusterInformation(Cluster cluster) {
private static ClusterDetails CollectClusterInformation(Cluster cluster, int time) {
var details = new ClusterDetails {
Pegs = new List<PegAddress>(),
ConnectingComponents = new List<ComponentAddress>(),
LinkingComponents = new List<ComponentAddress>(),
Color = HsvToRgb(time * 20, 1, 1),
};
// Two lists are never null, according to how it is created and used:
@ -247,5 +288,49 @@ namespace CriticalPathAnalyzer.Server.Tool {
return details;
}
private static int HsvToRgb(int h, float s, float v) {
s = Math.Clamp(s, 0, 1);
v = Math.Clamp(v, 0, 1);
h = (h % 360 + 360) % 360; // Ensure hue is within 0-359 range
float c = v * s;
float x = c * (1 - Math.Abs((h / 60.0f) % 2 - 1));
float m = v - c;
float r = 0, g = 0, b = 0;
if (h < 60) {
r = c;
g = x;
b = 0;
} else if (h < 120) {
r = x;
g = c;
b = 0;
} else if (h < 180) {
r = 0;
g = c;
b = x;
} else if (h < 240) {
r = 0;
g = x;
b = c;
} else if (h < 300) {
r = x;
g = 0;
b = c;
} else {
r = c;
g = 0;
b = x;
}
int rInt = (byte) ((r + m) * 255);
int gInt = (byte) ((g + m) * 255);
int bInt = (byte) ((b + m) * 255);
return (rInt << 16) | (gInt << 8) | bInt;
}
}
}

@ -9,8 +9,8 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
public class AnalyzePathResponse : Packet {
[Key(0)] public Guid RequestGuid;
[Key(1)] public List<ClusterDetails> Clusters;
[Key(2)] public List<ComponentAddress> PerimeterComponents;
[Key(3)] public List<ClusterDetails> NextClusters;
// [Key(2)] public List<ComponentAddress> PerimeterComponents;
// [Key(3)] public List<ClusterDetails> NextClusters;
}
[MessagePackObject]
@ -18,5 +18,6 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[Key(0)] public List<PegAddress> Pegs;
[Key(1)] public List<ComponentAddress> ConnectingComponents; // Sockets
[Key(2)] public List<ComponentAddress> LinkingComponents; // Relays, fast buffers
[Key(3)] public int Color;
}
}
Loading…
Cancel
Save