using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
namespace DigiSim.Logic.Gates {
public class CustomGate : Gate {
public int Inputs { get; }
public int Outputs { get; }
public string Symbol { get; }
public LookupTable Lookup { get; }
public CustomGate(double x, double y) : base(x, y, 50, 50) { }
private CustomGate(string symbol, LookupTable lookup) {
Symbol = symbol;
Lookup = lookup;
Inputs = lookup.InputCount;
Outputs = lookup.OutputCount;
Constructor(0, 0, 0, 0);
}
protected override void InternalSetup(Canvas canvas) {
Shape = new Rectangle();
int connectorCount = Math.Max(Inputs, Outputs);
Size = new Size(50, connectorCount * 25);
SetInputs(Inputs);
SetOutputs(Outputs);
CreateConnections();
Text = Symbol;
Instantiate();
}
public override void Update(Gate source) {
bool[] snapshot = new bool[ConnectedInputs.Length];
for (var i = 0; i < snapshot.Length; i++) {
snapshot[i] = ConnectedInputs[i].IsPowered;
}
bool[] outputs = Lookup.GetOutputs(snapshot);
for (var i = 0; i < ConnectedOutputs.Length; i++) {
ConnectedOutputs[i].IsPowered = outputs[i];
}
UpdateShapes();
UpdateConnectedGates(source);
}
public struct LookupTable {
public bool[,] Inputs { get; }
public bool[,] Outputs { get; }
public int InputCount { get; }
public int OutputCount { get; }
public int Length { get; }
public LookupTable(int inputCount, int outputCount, int length) {
Inputs = new bool[length, inputCount];
Outputs = new bool[length, outputCount];
InputCount = inputCount;
OutputCount = outputCount;
Length = length;
}
public bool[] GetOutputs(bool[] inputs) {
if (inputs.Length != InputCount) throw new ArgumentOutOfRangeException(nameof(inputs));
for (int i = 0; i < Length; i++) {
bool found = true;
for (int j = 0; j < InputCount; j++) {
if (Inputs[i, j] != inputs[j]) {
found = false;
break;
}
}
if (found) {
bool[] output = new bool[OutputCount];
for (int o = 0; o < OutputCount; o++) {
output[o] = Outputs[i, o];
}
return output;
}
}
return new bool[OutputCount];
}
public void SetLookup(bool[] inputs, bool[] outputs, int index) {
if (index >= Length) throw new IndexOutOfRangeException(nameof(index));
for (var i = 0; i < inputs.Length; i++) {
Inputs[index, i] = inputs[i];
}
for (var i = 0; i < outputs.Length; i++) {
Outputs[index, i] = outputs[i];
}
}
}
private static LookupTable CreateLookup(Gate[] gates) {
List inputs = new List();
List