protected virtual void GetOutput(bool forceUpdate) { int loops = 0; Queue <Guid> queue = new Queue <Guid>(); foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Wire wire in WireDict[ID]) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex]); chip.Update(forceUpdate); if (forceUpdate || GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex]); gate.Update(); if (forceUpdate || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 1000) { Console.WriteLine("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); } else { FromValues = Chips.Find(x => x.ID == guid).Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex]; } else { Chip chip = Chips[wire.CircuitIndex]; if (chip.Dirty[wire.FromIndex]) { chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex]); chip.Update(forceUpdate); if (forceUpdate || GetCardinality(Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex]); gate.Update(); if (forceUpdate || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } }
protected virtual void GetOutput(bool forceUpdate) { int loops = 0; UniqueQueue <Guid> queue = new UniqueQueue <Guid>(); UniqueQueue <Guid> outputQueue = new UniqueQueue <Guid>(); // This is a new update loops so make sure gates and chips are not dirty foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Gate gate in Gates) { gate.SetClean(); } // Update input wires foreach (Wire wire in WireDict[ID]) { if (forceUpdate || FirstRun || (OldInput[wire.FromIndex] != Input[wire.FromIndex])) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.InvertValue); chip.Update(forceUpdate); if (forceUpdate || FirstRun || chip.IsDirty()) { queue.Enqueue(chip.ID); } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.InvertValue); gate.Update(ScrubOutput); if (forceUpdate || FirstRun || gate.IsDirty()) { queue.Enqueue(gate.ID); } } } } //Update internal components while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 100) { Debug.Log("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; BitArray FromDirty; // The output of the previous gate Gate previousGate = FindGate(guid); if (previousGate != null) { FromValues = new BitArray(1, previousGate.Output); FromDirty = new BitArray(1, previousGate.IsDirty()); } else { Chip c = FindChip(guid); FromValues = c.Output; FromDirty = c.Dirty; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { outputQueue.Enqueue(guid); Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.InvertValue; //Debug.Log("Updated output: " + wire.ToIndex); } else if (FromDirty[wire.FromIndex]) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.InvertValue); chip.Update(false); //Debug.Log("Updated chip: " + (char)(Chips.FindIndex(x => x.ID == guid) + 65) + "->" + (char)(wire.CircuitIndex + 65)); if (chip.IsDirty()) { queue.Enqueue(chip.ID); } } } else if (FromDirty[wire.FromIndex]) { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.InvertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { queue.Enqueue(gate.ID); } } } } //Update output wires while (outputQueue.Count > 0) { Guid guid = outputQueue.Dequeue(); BitArray FromValues; Gate gate = FindGate(guid); if (gate != null) { FromValues = new BitArray(1, gate.Output); } else { FromValues = FindChip(guid).Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip && wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.InvertValue; } } } }
protected virtual void GetOutput(bool forceUpdate) { int loops = 0; Queue <Guid> queue = new Queue <Guid>(); Queue <Guid> outputQueue = new Queue <Guid>(); foreach (Chip chip in Chips) { chip.Dirty.SetAll(false); } foreach (Gate gate in Gates) { gate.SetClean(); } // Update input wires foreach (Wire wire in WireDict[ID]) { if (forceUpdate || FirstRun || (OldInput[wire.FromIndex] != Input[wire.FromIndex])) { if (wire.IsChip) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.invertValue); chip.Update(forceUpdate); //Debug.Log("Updated chip: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } else { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, Input[wire.FromIndex] ^ wire.invertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } //Update internal components while (queue.Count > 0) { //Stop infinite loops from continuing loops++; if (loops >= 100) { Debug.Log("Infinite loop, breaking"); return; } Guid guid = queue.Dequeue(); BitArray FromValues; BitArray FromDirty; // Find a better way to get values int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); FromDirty = new BitArray(1, Gates[findIndex].IsDirty()); } else { Chip c = Chips.Find(x => x.ID == guid); FromValues = c.Output; FromDirty = c.Dirty; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip) { if (wire.CircuitIndex == -1) { if (!outputQueue.Contains(guid)) { outputQueue.Enqueue(guid); } Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.invertValue; //Debug.Log("Updated output: " + wire.ToIndex); } else if (FromDirty[wire.FromIndex]) { Chip chip = Chips[wire.CircuitIndex]; chip.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.invertValue); chip.Update(false); //Debug.Log("Updated chip: " + (char)(Chips.FindIndex(x => x.ID == guid) + 65) + "->" + (char)(wire.CircuitIndex + 65)); if (GetCardinality(chip.Dirty) > 0) { if (!queue.Contains(chip.ID)) { queue.Enqueue(chip.ID); } } } } else if (FromDirty[wire.FromIndex]) { Gate gate = Gates[wire.CircuitIndex]; gate.SetInputBit(wire.ToIndex, FromValues[wire.FromIndex] ^ wire.invertValue); gate.Update(ScrubOutput); //Debug.Log("Updated gate: " + (char)(wire.CircuitIndex + 65)); if (forceUpdate || FirstRun || gate.IsDirty()) { if (!queue.Contains(gate.ID)) { queue.Enqueue(gate.ID); } } } } } //Update output wires while (outputQueue.Count > 0) { Guid guid = outputQueue.Dequeue(); BitArray FromValues; int findIndex = Gates.FindIndex(x => x.ID == guid); if (findIndex != -1) { FromValues = new BitArray(1, Gates[findIndex].Output); } else { Chip c = Chips.Find(x => x.ID == guid); FromValues = c.Output; } foreach (Wire wire in WireDict[guid]) { if (wire.IsChip && wire.CircuitIndex == -1) { Output[wire.ToIndex] = FromValues[wire.FromIndex] ^ wire.invertValue; } } } }