Make connection context menu more intuitive

This commit is contained in:
Stone_Red
2023-10-04 16:55:45 +02:00
parent 1f78c8e36e
commit e6be354884
3 changed files with 49 additions and 40 deletions
@@ -75,7 +75,7 @@ internal class LogicGateSimulator
logicGatesUpdated = logicGates.TryRemove(logicGate.Id, out _); logicGatesUpdated = logicGates.TryRemove(logicGate.Id, out _);
} }
public void SimulationThread() private void SimulationThread()
{ {
int tps = 0; int tps = 0;
float iterations = 10000; float iterations = 10000;
@@ -118,10 +118,12 @@ internal class LogicGateSimulator
ClockCalibrating = percentage > 5; ClockCalibrating = percentage > 5;
} }
} }
for (int i = 0; i < logicGatesArray.Length; i++) for (int i = 0; i < logicGatesArray.Length; i++)
{ {
logicGatesArray[i].NextTick(); logicGatesArray[i].NextTick();
} }
for (int i = 0; i < logicGatesArray.Length; i++) for (int i = 0; i < logicGatesArray.Length; i++)
{ {
logicGatesArray[i].Update(); logicGatesArray[i].Update();
@@ -4,7 +4,6 @@ using StoneRed.LogicSimulator.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces; namespace StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
#pragma warning disable S112 // General exceptions should never be thrown #pragma warning disable S112 // General exceptions should never be thrown
@@ -16,13 +15,23 @@ internal abstract class LogicGate
private int newInput; private int newInput;
private int output; private int output;
private int cachedOutput; private int cachedOutput;
public IReadOnlyList<LogicGateConnection> LogicGateConnections => logicGateConnections.AsReadOnly();
public abstract int OutputCount { get; set; }
public abstract int InputCount { get; set; }
internal GraphicsDevice? GraphicsDevice { get; set; } internal GraphicsDevice? GraphicsDevice { get; set; }
internal LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData(); internal LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData();
internal ulong Id { get; set; } internal ulong Id { get; set; }
public IReadOnlyList<LogicGateConnection> LogicGateConnections => logicGateConnections.AsReadOnly();
public abstract int OutputCount { get; set; }
public abstract int InputCount { get; set; } public override bool Equals(object? obj)
{
return obj is LogicGate gate &&
Id == gate.Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
internal void NextTick() internal void NextTick()
{ {
@@ -64,19 +73,25 @@ internal abstract class LogicGate
} }
} }
internal bool IsConnectedTo(LogicGate logicGate) internal bool IsConnectedTo(LogicGate logicGate, int? inputIndex = null, int? outputIndex = null)
{ {
lock (logicGateConnections) lock (logicGateConnections)
{ {
return logicGateConnections.Any(c => c.LogicGate.Id == logicGate.Id); return logicGateConnections.Exists(c =>
c.LogicGate.Id == logicGate.Id
&& (!inputIndex.HasValue || c.InputIndex == inputIndex)
&& (!outputIndex.HasValue || c.OutputIndex == outputIndex));
} }
} }
internal void Disconnect(LogicGate logicGate) internal void Disconnect(LogicGate logicGate, int? inputIndex = null, int? outputIndex = null)
{ {
lock (logicGateConnections) lock (logicGateConnections)
{ {
int index = logicGateConnections.FindIndex(c => c.LogicGate.Id == logicGate.Id); int index = logicGateConnections.FindIndex(c =>
c.LogicGate.Id == logicGate.Id &&
(!inputIndex.HasValue || c.InputIndex == inputIndex) &&
(!outputIndex.HasValue || c.OutputIndex == outputIndex));
logicGateConnections.RemoveAt(index); logicGateConnections.RemoveAt(index);
} }
} }
@@ -98,16 +113,8 @@ internal abstract class LogicGate
return cachedOutput.GetBit(index); return cachedOutput.GetBit(index);
} }
public override bool Equals(object? obj) protected internal virtual void Initialize()
{ { }
return obj is LogicGate gate &&
Id == gate.Id;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
protected abstract void Execute(); protected abstract void Execute();
@@ -14,12 +14,30 @@ internal class LogicGatesManager
{ {
private readonly GraphicsDevice graphicsDevice; private readonly GraphicsDevice graphicsDevice;
private readonly Dictionary<LogicGateInfo, Type> logicGates = new Dictionary<LogicGateInfo, Type>();
public LogicGatesManager(GraphicsDevice graphicsDevice) public LogicGatesManager(GraphicsDevice graphicsDevice)
{ {
this.graphicsDevice = graphicsDevice; this.graphicsDevice = graphicsDevice;
} }
private readonly Dictionary<LogicGateInfo, Type> logicGates = new Dictionary<LogicGateInfo, Type>(); public static string GetTypeLogicGateName(Type type)
{
LogicGateNameAttribute nameAttribute = (LogicGateNameAttribute)type.GetCustomAttributes(typeof(LogicGateNameAttribute), false)[0];
return nameAttribute.Name;
}
public static bool TryGetTypeLogicGateName(Type type, [NotNullWhen(true)] out string? typeName)
{
if (type.GetCustomAttributes(typeof(LogicGateNameAttribute), false).FirstOrDefault() is not LogicGateNameAttribute nameAttribute)
{
typeName = null;
return false;
}
typeName = nameAttribute.Name;
return true;
}
public void LoadLogicGates() public void LoadLogicGates()
{ {
@@ -55,28 +73,10 @@ internal class LogicGatesManager
LogicGate logicGate = (LogicGate)Activator.CreateInstance(type)!; LogicGate logicGate = (LogicGate)Activator.CreateInstance(type)!;
logicGate.GraphicsDevice = graphicsDevice; logicGate.GraphicsDevice = graphicsDevice;
logicGate.Initialize();
return logicGate; return logicGate;
} }
public static string GetTypeLogicGateName(Type type)
{
LogicGateNameAttribute nameAttribute = (LogicGateNameAttribute)type.GetCustomAttributes(typeof(LogicGateNameAttribute), false)[0];
return nameAttribute.Name;
}
public static bool TryGetTypeLogicGateName(Type type, [NotNullWhen(true)] out string? typeName)
{
if (type.GetCustomAttributes(typeof(LogicGateNameAttribute), false).FirstOrDefault() is not LogicGateNameAttribute nameAttribute)
{
typeName = null;
return false;
}
typeName = nameAttribute.Name;
return true;
}
public bool TryCreateLogicGate(string typeName, [NotNullWhen(true)] out LogicGate? logicGate) public bool TryCreateLogicGate(string typeName, [NotNullWhen(true)] out LogicGate? logicGate)
{ {
if (!logicGates.ContainsKey(new LogicGateInfo(typeName, null))) if (!logicGates.ContainsKey(new LogicGateInfo(typeName, null)))
@@ -89,7 +89,7 @@ internal class LogicGatesManager
logicGate = (LogicGate)Activator.CreateInstance(type)!; logicGate = (LogicGate)Activator.CreateInstance(type)!;
logicGate.GraphicsDevice = graphicsDevice; logicGate.GraphicsDevice = graphicsDevice;
logicGate.Initialize();
return true; return true;
} }
} }