예제 #1
0
 private Chip FindChip(Guid id)
 {
     if (!ChipDict.ContainsKey(id))
     {
         ChipDict[id] = Chips.Find(x => x.ID == id);
     }
     return(ChipDict[id]);
 }
예제 #2
0
파일: Chip.cs 프로젝트: polklabs/Logical
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        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;
                    }
                }
            }
        }