Exchanged all Bit[] by BitVector, tests work
authorChristian Femers <femers@in.tum.de>
Mon, 20 May 2019 16:24:49 +0000 (18:24 +0200)
committerChristian Femers <femers@in.tum.de>
Mon, 20 May 2019 16:24:49 +0000 (18:24 +0200)
Some things can still be improved, but it should be way more readable
now.

15 files changed:
era.mi/src/era/mi/logic/components/BasicComponent.java
era.mi/src/era/mi/logic/components/BitDisplay.java
era.mi/src/era/mi/logic/components/Connector.java
era.mi/src/era/mi/logic/components/Merger.java
era.mi/src/era/mi/logic/components/Splitter.java
era.mi/src/era/mi/logic/components/gates/AndGate.java
era.mi/src/era/mi/logic/components/gates/MultiInputGate.java
era.mi/src/era/mi/logic/components/gates/NotGate.java
era.mi/src/era/mi/logic/components/gates/OrGate.java
era.mi/src/era/mi/logic/components/gates/XorGate.java
era.mi/src/era/mi/logic/tests/ComponentTest.java
era.mi/src/era/mi/logic/tests/TestBitDisplay.java
era.mi/src/era/mi/logic/types/BitVector.java
era.mi/src/era/mi/logic/wires/Wire.java
era.mi/src/era/mi/logic/wires/WireObserver.java

index 0a22950..e695283 100644 (file)
@@ -1,7 +1,7 @@
 package era.mi.logic.components;
 
 import era.mi.logic.Simulation;
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.WireObserver;
 
@@ -26,7 +26,7 @@ public abstract class BasicComponent implements WireObserver, Component
        }
 
        @Override
-       public void update(Wire initiator, Bit[] oldValues)
+       public void update(Wire initiator, BitVector oldValues)
        {
                Simulation.TIMELINE.addEvent(e -> compute(), processTime);
        }
index 3da693b..971eb7a 100644 (file)
@@ -1,15 +1,15 @@
 package era.mi.logic.components;
 
-import java.util.Arrays;
 import java.util.List;
 
 import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire.WireEnd;
 
 public class BitDisplay extends BasicComponent
 {
        private final WireEnd in;
-       private Bit[] displayedValue;
+       private BitVector displayedValue;
 
        public BitDisplay(WireEnd in)
        {
@@ -25,14 +25,14 @@ public class BitDisplay extends BasicComponent
                displayedValue = in.getValues();
        }
 
-       public Bit[] getDisplayedValue()
+       public BitVector getDisplayedValue()
        {
                return displayedValue;
        }
 
        public boolean isDisplaying(Bit... values)
        {
-               return Arrays.equals(displayedValue, values);
+               return displayedValue.equals(BitVector.of(values));
        }
 
        @Override
index aa8c437..89fb96e 100644 (file)
@@ -3,7 +3,7 @@ package era.mi.logic.components;
 import java.util.List;
 
 import era.mi.logic.Simulation;
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.Wire.WireEnd;
 import era.mi.logic.wires.WireObserver;
@@ -47,7 +47,7 @@ public class Connector implements WireObserver, Component
        }
 
        @Override
-       public void update(Wire initiator, Bit[] oldValues)
+       public void update(Wire initiator, BitVector oldValues)
        {
                if (connected)
                        Simulation.TIMELINE.addEvent(e -> update(initiator), 1);
index ca441ba..34ba217 100644 (file)
@@ -2,7 +2,7 @@ package era.mi.logic.components;
 
 import java.util.List;
 
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.Wire.WireEnd;
 import era.mi.logic.wires.WireObserver;
@@ -48,7 +48,7 @@ public class Merger implements WireObserver, Component
        }
 
        @Override
-       public void update(Wire initiator, Bit[] oldValues)
+       public void update(Wire initiator, BitVector oldValues)
        {
                int index = find(initiator);
                int beginning = beginningIndex[index];
index 09321f1..4764c27 100644 (file)
@@ -1,6 +1,6 @@
 package era.mi.logic.components;
 
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.Wire.WireEnd;
 import era.mi.logic.wires.WireObserver;
@@ -26,19 +26,17 @@ public class Splitter implements WireObserver
 
        protected void compute()
        {
+               BitVector inputBits = input.getValues();
                int startIndex = 0;
-               Bit[] inputBits = input.getValues();
                for (int i = 0; i < outputs.length; i++)
                {
-                       Bit[] outputBits = new Bit[outputs[i].length()];
-                       System.arraycopy(inputBits, startIndex, outputBits, 0, outputs[i].length());
-                       outputs[i].feedSignals(outputBits);
+                       outputs[i].feedSignals(inputBits.subVector(startIndex, startIndex + outputs[i].length()));
                        startIndex += outputs[i].length();
                }
        }
 
        @Override
-       public void update(Wire initiator, Bit[] oldValues)
+       public void update(Wire initiator, BitVector oldValues)
        {
                compute();
        }
index 2722f03..5da680e 100644 (file)
@@ -1,12 +1,12 @@
 package era.mi.logic.components.gates;
 
-import era.mi.logic.Util;
+import era.mi.logic.types.BitVector.BitVectorMutator;
 import era.mi.logic.wires.Wire.WireEnd;
 
 public class AndGate extends MultiInputGate
 {
        public AndGate(int processTime, WireEnd out, WireEnd... in)
        {
-               super(processTime, Util::and, out, in);
+               super(processTime, BitVectorMutator::and, out, in);
        }
 }
index 2b0a529..0b4a5d0 100644 (file)
@@ -3,7 +3,8 @@ package era.mi.logic.components.gates;
 import java.util.List;
 
 import era.mi.logic.components.BasicComponent;
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector.BitVectorMutator;
+import era.mi.logic.types.MutationOperation;
 import era.mi.logic.wires.Wire.WireEnd;
 
 public abstract class MultiInputGate extends BasicComponent
@@ -11,9 +12,9 @@ public abstract class MultiInputGate extends BasicComponent
        protected WireEnd[] in;
        protected WireEnd out;
        protected final int length;
-       protected Operation op;
+       protected MutationOperation op;
 
-       protected MultiInputGate(int processTime, Operation op, WireEnd out, WireEnd... in)
+       protected MultiInputGate(int processTime, MutationOperation op, WireEnd out, WireEnd... in)
        {
                super(processTime);
                this.op = op;
@@ -45,14 +46,9 @@ public abstract class MultiInputGate extends BasicComponent
        @Override
        protected void compute()
        {
-               Bit[] result = in[0].getValues();
-               for (int i = 1; i < in.length; i++)
-                       result = op.execute(result, in[i].getValues());
-               out.feedSignals(result);
-       }
-
-       protected interface Operation
-       {
-               public Bit[] execute(Bit[] a, Bit[] b);
+               BitVectorMutator mutator = BitVectorMutator.empty();
+               for (WireEnd w : in)
+                       op.apply(mutator, w.getValues());
+               out.feedSignals(mutator.get());
        }
 }
index 6829dc3..1c0d833 100644 (file)
@@ -2,7 +2,6 @@ package era.mi.logic.components.gates;
 
 import java.util.List;
 
-import era.mi.logic.Util;
 import era.mi.logic.components.BasicComponent;
 import era.mi.logic.wires.Wire.WireEnd;
 
@@ -22,7 +21,7 @@ public class NotGate extends BasicComponent
        @Override
        protected void compute()
        {
-               out.feedSignals(Util.not(in.getValues()));
+               out.feedSignals(in.getValues().not());
        }
 
        public WireEnd getIn()
index ba8262a..8c1775f 100644 (file)
@@ -1,12 +1,12 @@
 package era.mi.logic.components.gates;
 
-import era.mi.logic.Util;
+import era.mi.logic.types.BitVector.BitVectorMutator;
 import era.mi.logic.wires.Wire.WireEnd;
 
 public class OrGate extends MultiInputGate
 {
        public OrGate(int processTime, WireEnd out, WireEnd... in)
        {
-               super(processTime, Util::or, out, in);
+               super(processTime, BitVectorMutator::or, out, in);
        }
 }
index 71fcb21..73a2556 100644 (file)
@@ -1,6 +1,6 @@
 package era.mi.logic.components.gates;
 
-import era.mi.logic.Util;
+import era.mi.logic.types.BitVector.BitVectorMutator;
 import era.mi.logic.wires.Wire.WireEnd;
 
 /**
@@ -12,7 +12,7 @@ public class XorGate extends MultiInputGate
 {
        public XorGate(int processTime, WireEnd out, WireEnd... in)
        {
-               super(processTime, Util::xor, out, in);
+               super(processTime, BitVectorMutator::xor, out, in);
        }
 
 }
index cb2195e..8a9bc5a 100644 (file)
@@ -2,7 +2,6 @@ package era.mi.logic.tests;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-import java.util.Arrays;
 import java.util.function.LongConsumer;
 
 import org.junit.jupiter.api.Test;
@@ -19,6 +18,7 @@ import era.mi.logic.components.gates.NotGate;
 import era.mi.logic.components.gates.OrGate;
 import era.mi.logic.components.gates.XorGate;
 import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.Wire.WireEnd;
 
@@ -78,8 +78,7 @@ class ComponentTest
 
                Simulation.TIMELINE.executeAll();
 
-               assertTrue(
-                               Arrays.equals(out.getValues(), new Bit[] { Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE }));
+               assertBitArrayEquals(out.getValues(), Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO, Bit.ONE);
        }
 
        @Test
@@ -378,8 +377,8 @@ class ComponentTest
                test2.assertAfterSimulationIs(Bit.ONE);
        }
 
-       private static void assertBitArrayEquals(Bit[] actual, Bit... expected)
+       private static void assertBitArrayEquals(BitVector actual, Bit... expected)
        {
-               assertArrayEquals(expected, actual);
+               assertArrayEquals(expected, actual.getBits());
        }
 }
index a07125d..cb0494e 100644 (file)
@@ -2,7 +2,6 @@ package era.mi.logic.tests;
 
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 
-import java.util.Arrays;
 import java.util.function.LongConsumer;
 
 import era.mi.logic.Simulation;
@@ -20,7 +19,7 @@ public final class TestBitDisplay extends BitDisplay
 
        public void assertDisplays(Bit... expected)
        {
-               assertArrayEquals(expected, getDisplayedValue());
+               assertArrayEquals(expected, getDisplayedValue().getBits());
        }
 
        public void assertAfterSimulationIs(Bit... expected)
@@ -43,6 +42,6 @@ public final class TestBitDisplay extends BitDisplay
        protected void compute()
        {
                super.compute();
-               System.out.println("update: value is " + Arrays.toString(getDisplayedValue()));
+               System.out.println("update: value is " + getDisplayedValue());
        }
 }
index 51545f7..38d7d26 100644 (file)
@@ -255,7 +255,7 @@ public final class BitVector implements StrictLogicType<BitVector>, Iterable<Bit
         * 
         * @see Object#equals(Object)
         */
-       public boolean equals(BitVector other, int offset)
+       public boolean equalsWithOffset(BitVector other, int offset)
        {
                if (other == null)
                        return false;
index db93253..a7b96ee 100644 (file)
@@ -1,13 +1,14 @@
 package era.mi.logic.wires;
 
+import static era.mi.logic.types.Bit.*;
+
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
 import java.util.List;
 
 import era.mi.logic.Simulation;
-import era.mi.logic.Util;
 import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
+import era.mi.logic.types.BitVector.BitVectorMutator;
 
 /**
  * Represents an array of wires that can store n bits of information.
@@ -17,7 +18,7 @@ import era.mi.logic.types.Bit;
  */
 public class Wire
 {
-       private Bit[] values;
+       private BitVector values;
        public final int travelTime;
        private List<WireObserver> observers = new ArrayList<WireObserver>();
        public final int length;
@@ -35,41 +36,29 @@ public class Wire
 
        private void initValues()
        {
-               values = Bit.U.makeArray(length);
+               values = U.toVector(length);
        }
 
        private void recalculateSingleInput()
        {
-               WireEnd input = inputs.get(0);
-               if (!Arrays.equals(input.getInputValues(), values))
-               {
-                       Bit[] oldValues = values.clone();
-                       System.arraycopy(input.getInputValues(), 0, values, 0, length);
-                       notifyObservers(oldValues);
-               }
+               setNewValues(inputs.get(0).getInputValues());
        }
 
        private void recalculateMultipleInputs()
        {
-               Iterator<WireEnd> it = inputs.iterator();
-               Bit[] newValues = it.next().inputValues.clone();
-
-               while (it.hasNext())
-               {
-                       WireEnd input = it.next();
-                       Bit[] bits = input.getInputValues();
-                       for (int i = 0; i < length; i++)
-                       {
-                               newValues[i] = newValues[i].join(bits[i]);
-                       }
-               }
+               BitVectorMutator mutator = BitVectorMutator.empty();
+               for (WireEnd wireArrayEnd : inputs)
+                       mutator.join(wireArrayEnd.getInputValues());
+               setNewValues(mutator.get());
+       }
 
-               if (!Arrays.equals(newValues, values))
-               {
-                       Bit[] oldValues = values;
-                       values = newValues;
-                       notifyObservers(oldValues);
-               }
+       private void setNewValues(BitVector newValues)
+       {
+               if (values.equals(newValues))
+                       return;
+               BitVector oldValues = values;
+               values = newValues;
+               notifyObservers(oldValues);
        }
 
        private void recalculate()
@@ -115,9 +104,9 @@ public class Wire
        {
                long val = 0;
                long mask = 1;
-               for (int i = 0; i < length; i++)
+               for (Bit bit : values)
                {
-                       switch (values[i])
+                       switch (bit)
                        {
                        default:
                        case Z:
@@ -160,20 +149,17 @@ public class Wire
 
        public Bit getValue(int index)
        {
-               return values[index];
+               return values.getBit(index);
        }
 
-       public Bit[] getValues(int start, int end)
+       public BitVector getValues(int start, int end)
        {
-               int length = end - start;
-               Bit[] bits = new Bit[length];
-               System.arraycopy(values, start, bits, 0, length);
-               return bits;
+               return values.subVector(start, end);
        }
 
-       public Bit[] getValues()
+       public BitVector getValues()
        {
-               return values.clone();
+               return values;
        }
 
        /**
@@ -189,7 +175,7 @@ public class Wire
                return observers.add(ob);
        }
 
-       private void notifyObservers(Bit[] oldValues)
+       private void notifyObservers(BitVector oldValues)
        {
                for (WireObserver o : observers)
                        o.update(this, oldValues);
@@ -226,12 +212,12 @@ public class Wire
        public class WireEnd
        {
                private boolean open;
-               private Bit[] inputValues;
+               private BitVector inputValues;
 
                private WireEnd(boolean readOnly)
                {
                        super();
-                       open = true;
+                       open = !readOnly; // TODO: that makes sense, doesn't it?
                        initValues();
                        if (!readOnly)
                                registerInput(this);
@@ -239,7 +225,7 @@ public class Wire
 
                private void initValues()
                {
-                       inputValues = Bit.U.makeArray(length);
+                       inputValues = U.toVector(length);
                }
 
                /**
@@ -251,41 +237,54 @@ public class Wire
                 */
                public void feedSignals(Bit... newValues)
                {
-                       if (newValues.length != length)
+                       feedSignals(BitVector.of(newValues));
+               }
+
+               public void feedSignals(BitVector newValues)
+               {
+                       if (newValues.length() != length)
                                throw new IllegalArgumentException(
-                                               String.format("Attempted to input %d bits instead of %d bits.", newValues.length, length));
-                       feedSignals(0, newValues);
+                                               String.format("Attempted to input %d bits instead of %d bits.", newValues.length(), length));
+                       if (!open)
+                               throw new RuntimeException("Attempted to write to closed WireArrayEnd.");
+                       Simulation.TIMELINE.addEvent(e -> setValues(newValues), travelTime);
                }
 
                /**
                 * Sets values of a subarray of wires. This takes up time, as specified by the {@link Wire}s travel time.
                 * 
-                * @param newValues   The new values the wires should take on.
+                * @param bitVector   The new values the wires should take on.
                 * @param startingBit The first index of the subarray of wires.
                 * 
                 * @author Fabian Stemmler
                 */
-               public void feedSignals(int startingBit, Bit... newValues)
+               public void feedSignals(int startingBit, BitVector bitVector)
                {
                        if (!open)
                                throw new RuntimeException("Attempted to write to closed WireArrayEnd.");
-                       Simulation.TIMELINE.addEvent((e) -> setValues(startingBit, newValues), travelTime);
+                       Simulation.TIMELINE.addEvent(e -> setValues(startingBit, bitVector), travelTime);
                }
 
-               private void setValues(int startingBit, Bit... newValues)
+               private void setValues(int startingBit, BitVector newValues)
                {
-                       int exclLastIndex = startingBit + newValues.length;
-                       if (length < exclLastIndex)
-                               throw new ArrayIndexOutOfBoundsException(
-                                               String.format("Attempted to input bits from index %d to %d when there are only %d wires.", startingBit,
-                                                               exclLastIndex - 1, length));
-                       if (!Arrays.equals(inputValues, startingBit, exclLastIndex, newValues, 0, newValues.length))
+                       // index check covered in equals
+                       if (!inputValues.equalsWithOffset(newValues, startingBit))
                        {
-                               System.arraycopy(newValues, 0, inputValues, startingBit, newValues.length);
+                               Bit[] vals = inputValues.getBits();
+                               System.arraycopy(newValues.getBits(), 0, vals, startingBit, newValues.length());
+                               inputValues = BitVector.of(vals);
                                Wire.this.recalculate();
                        }
                }
 
+               private void setValues(BitVector newValues)
+               {
+                       if (inputValues.equals(newValues))
+                               return;
+                       inputValues = newValues;
+                       Wire.this.recalculate();
+               }
+
                /**
                 * @return The value (of bit 0) the {@link WireEnd} is currently feeding into the associated {@link Wire}.
                 */
@@ -299,23 +298,20 @@ public class Wire
                 */
                public Bit getInputValue(int index)
                {
-                       return inputValues[index];
+                       return inputValues.getBit(index);
                }
 
                /**
                 * @return A copy (safe to modify) of the values the {@link WireEnd} is currently feeding into the associated {@link Wire}.
                 */
-               public Bit[] getInputValues()
+               public BitVector getInputValues()
                {
                        return getInputValues(0, length);
                }
 
-               public Bit[] getInputValues(int start, int end)
+               public BitVector getInputValues(int start, int end)
                {
-                       int length = end - start;
-                       Bit[] bits = new Bit[length];
-                       System.arraycopy(inputValues, start, bits, 0, length);
-                       return bits;
+                       return inputValues.subVector(start, end);
                }
 
                /**
@@ -323,19 +319,19 @@ public class Wire
                 */
                public void clearSignals()
                {
-                       feedSignals(Bit.Z.makeArray(length));
+                       feedSignals(Z.toVector(length));
                }
 
-               public Bit[] wireValuesExcludingMe()
+               public BitVector wireValuesExcludingMe()
                {
-                       Bit[] bits = Bit.Z.makeArray(length);
-                       for (WireEnd wai : inputs)
+                       BitVectorMutator mutator = BitVectorMutator.empty();
+                       for (WireEnd wireEnd : inputs)
                        {
-                               if (wai == this)
+                               if (wireEnd == this)
                                        continue;
-                               Util.combineInto(bits, wai.getInputValues());
+                               mutator.join(wireEnd.inputValues);
                        }
-                       return bits;
+                       return mutator.get();
                }
 
                /**
@@ -367,7 +363,7 @@ public class Wire
                 * 
                 * @author Fabian Stemmler
                 */
-               public Bit[] getValues()
+               public BitVector getValues()
                {
                        return Wire.this.getValues();
                }
@@ -379,7 +375,7 @@ public class Wire
                 * 
                 * @author Fabian Stemmler
                 */
-               public Bit[] getValues(int start, int end)
+               public BitVector getValues(int start, int end)
                {
                        return Wire.this.getValues(start, end);
                }
@@ -424,7 +420,7 @@ public class Wire
                @Override
                public String toString()
                {
-                       return Arrays.toString(inputValues);
+                       return inputValues.toString();
                        // return String.format("%s \nFeeding: %s", WireArray.this.toString(), Arrays.toString(inputValues));
                }
 
@@ -453,7 +449,7 @@ public class Wire
        @Override
        public String toString()
        {
-               return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), Arrays.toString(values), inputs);
+               return String.format("wire 0x%08x value: %s inputs: %s", hashCode(), values, inputs);
                // Arrays.toString(values), inputs.stream().map(i -> Arrays.toString(i.inputValues)).reduce((s1, s2) -> s1 + s2)
        }
 
index 0b52ff8..9258e0a 100644 (file)
@@ -1,8 +1,8 @@
 package era.mi.logic.wires;
 
-import era.mi.logic.types.Bit;
+import era.mi.logic.types.BitVector;
 
 public interface WireObserver
 {
-       public void update(Wire initiator, Bit[] oldValues);
+       public void update(Wire initiator, BitVector oldValues);
 }