WireEnd functionality split into ReadEnd and ReadWriteEnd
authorFabian Stemmler <stemmler@in.tum.de>
Fri, 24 May 2019 22:12:15 +0000 (00:12 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Fri, 24 May 2019 22:12:15 +0000 (00:12 +0200)
20 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/Clock.java
era.mi/src/era/mi/logic/components/Component.java
era.mi/src/era/mi/logic/components/Connector.java
era.mi/src/era/mi/logic/components/Demux.java
era.mi/src/era/mi/logic/components/ManualSwitch.java
era.mi/src/era/mi/logic/components/Merger.java
era.mi/src/era/mi/logic/components/Mux.java
era.mi/src/era/mi/logic/components/Splitter.java
era.mi/src/era/mi/logic/components/TriStateBuffer.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/wires/Wire.java
era.mi/src/era/mi/logic/wires/WireObserver.java

index e695283..f89a72c 100644 (file)
@@ -2,7 +2,7 @@ package era.mi.logic.components;
 
 import era.mi.logic.Simulation;
 import era.mi.logic.types.BitVector;
-import era.mi.logic.wires.Wire;
+import era.mi.logic.wires.Wire.ReadEnd;
 import era.mi.logic.wires.WireObserver;
 
 /**
@@ -26,7 +26,7 @@ public abstract class BasicComponent implements WireObserver, Component
        }
 
        @Override
-       public void update(Wire initiator, BitVector oldValues)
+       public void update(ReadEnd initiator, BitVector oldValues)
        {
                Simulation.TIMELINE.addEvent(e -> compute(), processTime);
        }
index 971eb7a..f34c923 100644 (file)
@@ -4,14 +4,15 @@ import java.util.List;
 
 import era.mi.logic.types.Bit;
 import era.mi.logic.types.BitVector;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class BitDisplay extends BasicComponent
 {
-       private final WireEnd in;
+       private final ReadEnd in;
        private BitVector displayedValue;
 
-       public BitDisplay(WireEnd in)
+       public BitDisplay(ReadEnd in)
        {
                super(1);
                this.in = in;
@@ -36,13 +37,13 @@ public class BitDisplay extends BasicComponent
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(in);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of();
        }
index 07419b4..f764855 100644 (file)
@@ -7,12 +7,13 @@ import era.mi.logic.timeline.TimelineEvent;
 import era.mi.logic.timeline.TimelineEventHandler;
 import era.mi.logic.types.Bit;
 import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class Clock implements TimelineEventHandler, Component
 {
        private boolean toggle = false;
-       private WireEnd out;
+       private ReadWriteEnd out;
        private int delta;
 
        /**
@@ -20,7 +21,7 @@ public class Clock implements TimelineEventHandler, Component
         * @param out   {@link Wire} the clock's impulses are fed into
         * @param delta ticks between rising and falling edge
         */
-       public Clock(WireEnd out, int delta)
+       public Clock(ReadWriteEnd out, int delta)
        {
                this.delta = delta;
                this.out = out;
@@ -35,7 +36,7 @@ public class Clock implements TimelineEventHandler, Component
                toggle = !toggle;
        }
 
-       public WireEnd getOut()
+       public ReadWriteEnd getOut()
        {
                return out;
        }
@@ -46,13 +47,13 @@ public class Clock implements TimelineEventHandler, Component
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of();
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
index 522a58d..f104e5f 100644 (file)
@@ -2,7 +2,8 @@ package era.mi.logic.components;
 
 import java.util.List;
 
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public interface Component
 {
@@ -11,10 +12,10 @@ public interface Component
         * Returns immutable list of all inputs to the {@link Component} (including e.g. the select bits to a MUX). Intended for visualization
         * in the UI.
         */
-       public List<WireEnd> getAllInputs();
+       public List<ReadEnd> getAllInputs();
 
        /**
         * Returns immutable list of all outputs to the {@link Component}. Intended for visualization in the UI.
         */
-       public List<WireEnd> getAllOutputs();
+       public List<ReadWriteEnd> getAllOutputs();
 }
index 89fb96e..19367a5 100644 (file)
@@ -4,17 +4,17 @@ import java.util.List;
 
 import era.mi.logic.Simulation;
 import era.mi.logic.types.BitVector;
-import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 import era.mi.logic.wires.WireObserver;
 
 public class Connector implements WireObserver, Component
 {
        private boolean connected;
-       private final WireEnd a;
-       private final WireEnd b;
+       private final ReadWriteEnd a;
+       private final ReadWriteEnd b;
 
-       public Connector(WireEnd a, WireEnd b)
+       public Connector(ReadWriteEnd a, ReadWriteEnd b)
        {
                if (a.length() != b.length())
                        throw new IllegalArgumentException(String.format("WireArray width does not match: %d, %d", a.length(), b.length()));
@@ -27,8 +27,8 @@ public class Connector implements WireObserver, Component
        public void connect()
        {
                connected = true;
-               update(a.getWire());
-               update(b.getWire());
+               update(a);
+               update(b);
        }
 
        public void disconnect()
@@ -47,28 +47,28 @@ public class Connector implements WireObserver, Component
        }
 
        @Override
-       public void update(Wire initiator, BitVector oldValues)
+       public void update(ReadEnd initiator, BitVector oldValues)
        {
                if (connected)
                        Simulation.TIMELINE.addEvent(e -> update(initiator), 1);
        }
 
-       private void update(Wire initiator)
+       private void update(ReadEnd initiator)
        {
-               if (initiator == a.getWire())
+               if (initiator == a)
                        b.feedSignals(a.wireValuesExcludingMe());
                else
                        a.feedSignals(b.wireValuesExcludingMe());
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(a, b);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(a, b);
        }
index 147dd7f..2182596 100644 (file)
@@ -3,7 +3,8 @@ package era.mi.logic.components;
 import java.util.List;
 
 import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 /**
  * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the
@@ -14,8 +15,8 @@ import era.mi.logic.wires.Wire.WireEnd;
  */
 public class Demux extends BasicComponent
 {
-       private final WireEnd select, in;
-       private final WireEnd[] outputs;
+       private final ReadEnd select, in;
+       private final ReadWriteEnd[] outputs;
        private final int outputSize;
        private int selected = -1;
 
@@ -26,7 +27,7 @@ public class Demux extends BasicComponent
         * @param select  Indexes the output array to which the input is mapped. Must have enough bits to index all outputs.
         * @param outputs One of these outputs receives the input signal, depending on the select bits
         */
-       public Demux(int processTime, WireEnd in, WireEnd select, WireEnd... outputs)
+       public Demux(int processTime, ReadEnd in, ReadEnd select, ReadWriteEnd... outputs)
        {
                super(processTime);
                outputSize = in.length();
@@ -67,13 +68,13 @@ public class Demux extends BasicComponent
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(in, select);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(outputs);
        }
index 0ad4a76..caaf49b 100644 (file)
@@ -3,7 +3,8 @@ package era.mi.logic.components;
 import java.util.List;
 
 import era.mi.logic.types.Bit;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 /**
  * This class models a simple on/off (ONE/ZERO) switch for user interaction.
@@ -13,10 +14,10 @@ import era.mi.logic.wires.Wire.WireEnd;
  */
 public class ManualSwitch implements Component
 {
-       private WireEnd output;
+       private ReadWriteEnd output;
        private boolean isOn;
 
-       public ManualSwitch(WireEnd output)
+       public ManualSwitch(ReadWriteEnd output)
        {
                if (output.length() != 1)
                        throw new IllegalArgumentException("Switch output can be only a single wire");
@@ -57,13 +58,13 @@ public class ManualSwitch implements Component
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of();
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(output);
        }
index 34ba217..a9d1410 100644 (file)
@@ -4,13 +4,14 @@ import java.util.List;
 
 import era.mi.logic.types.BitVector;
 import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 import era.mi.logic.wires.WireObserver;
 
 public class Merger implements WireObserver, Component
 {
-       private WireEnd out;
-       private WireEnd[] inputs;
+       private ReadWriteEnd out;
+       private ReadEnd[] inputs;
        private int[] beginningIndex;
 
        /**
@@ -18,7 +19,7 @@ public class Merger implements WireObserver, Component
         * @param union  The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length().
         * @param inputs The inputs to be merged into the union
         */
-       public Merger(WireEnd union, WireEnd... inputs)
+       public Merger(ReadWriteEnd union, ReadEnd... inputs)
        {
                this.inputs = inputs;
                this.out = union;
@@ -37,45 +38,45 @@ public class Merger implements WireObserver, Component
                                        "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length().");
        }
 
-       public WireEnd getInput(int index)
+       public ReadEnd getInput(int index)
        {
                return inputs[index];
        }
 
-       public WireEnd getUnion()
+       public ReadEnd getUnion()
        {
                return out;
        }
 
        @Override
-       public void update(Wire initiator, BitVector oldValues)
+       public void update(ReadEnd initiator, BitVector oldValues)
        {
                int index = find(initiator);
                int beginning = beginningIndex[index];
                out.feedSignals(beginning, inputs[index].getValues());
        }
 
-       private int find(Wire w)
+       private int find(ReadEnd r)
        {
                for (int i = 0; i < inputs.length; i++)
-                       if (inputs[i].getWire() == w)
+                       if (inputs[i] == r)
                                return i;
                return -1;
        }
 
-       public WireEnd[] getInputs()
+       public ReadEnd[] getInputs()
        {
                return inputs.clone();
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(inputs);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
index aea7116..b7cb674 100644 (file)
@@ -6,7 +6,8 @@ import java.util.Collections;
 import java.util.List;
 
 import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 /**
  * Models a multiplexer. Takes an arbitrary amount of input {@link Wire}s, one of which, as determined by select, is put through to the
@@ -17,9 +18,9 @@ import era.mi.logic.wires.Wire.WireEnd;
  */
 public class Mux extends BasicComponent
 {
-       private WireEnd select;
-       private WireEnd out;
-       private WireEnd[] inputs;
+       private ReadEnd select;
+       private ReadWriteEnd out;
+       private ReadEnd[] inputs;
        private final int outputSize;
 
        /**
@@ -29,7 +30,7 @@ public class Mux extends BasicComponent
         * @param select Indexes the input array which is to be mapped to the output. Must have enough bits to index all inputs.
         * @param inputs One of these inputs is mapped to the output, depending on the select bits
         */
-       public Mux(int processTime, WireEnd out, WireEnd select, WireEnd... inputs)
+       public Mux(int processTime, ReadWriteEnd out, ReadEnd select, ReadEnd... inputs)
        {
                super(processTime);
                outputSize = out.length();
@@ -53,12 +54,12 @@ public class Mux extends BasicComponent
                this.out = out;
        }
 
-       public WireEnd getOut()
+       public ReadEnd getOut()
        {
                return out;
        }
 
-       public WireEnd getSelect()
+       public ReadEnd getSelect()
        {
                return select;
        }
@@ -73,20 +74,20 @@ public class Mux extends BasicComponent
                        return;
                }
 
-               WireEnd active = inputs[selectValue];
+               ReadEnd active = inputs[selectValue];
                out.feedSignals(active.getValues());
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
-               ArrayList<WireEnd> wires = new ArrayList<WireEnd>(Arrays.asList(inputs));
+               ArrayList<ReadEnd> wires = new ArrayList<ReadEnd>(Arrays.asList(inputs));
                wires.add(select);
                return Collections.unmodifiableList(wires);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
index 4764c27..32841ab 100644 (file)
@@ -1,22 +1,24 @@
 package era.mi.logic.components;
 
+import java.util.List;
+
 import era.mi.logic.types.BitVector;
-import era.mi.logic.wires.Wire;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 import era.mi.logic.wires.WireObserver;
 
-public class Splitter implements WireObserver
+public class Splitter implements WireObserver, Component
 {
-       private WireEnd input;
-       private WireEnd[] outputs;
+       private ReadEnd input;
+       private ReadWriteEnd[] outputs;
 
-       public Splitter(WireEnd input, WireEnd... outputs)
+       public Splitter(ReadEnd input, ReadWriteEnd... outputs)
        {
                this.input = input;
                this.outputs = outputs;
                input.addObserver(this);
                int length = 0;
-               for (WireEnd out : outputs)
+               for (ReadEnd out : outputs)
                        length += out.length();
 
                if (input.length() != length)
@@ -36,8 +38,20 @@ public class Splitter implements WireObserver
        }
 
        @Override
-       public void update(Wire initiator, BitVector oldValues)
+       public void update(ReadEnd initiator, BitVector oldValues)
        {
                compute();
        }
+
+       @Override
+       public List<ReadEnd> getAllInputs()
+       {
+               return List.of(input);
+       }
+
+       @Override
+       public List<ReadWriteEnd> getAllOutputs()
+       {
+               return List.of(outputs);
+       }
 }
index c0dd76e..ee42056 100644 (file)
@@ -3,14 +3,15 @@ package era.mi.logic.components;
 import java.util.List;
 
 import era.mi.logic.types.Bit;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class TriStateBuffer extends BasicComponent
 {
-       WireEnd in, enable;
-       WireEnd out;
+       ReadEnd in, enable;
+       ReadWriteEnd out;
 
-       public TriStateBuffer(int processTime, WireEnd in, WireEnd out, WireEnd enable)
+       public TriStateBuffer(int processTime, ReadEnd in, ReadWriteEnd out, ReadEnd enable)
        {
                super(processTime);
                if (in.length() != out.length())
@@ -35,13 +36,13 @@ public class TriStateBuffer extends BasicComponent
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(in, enable);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
index 5da680e..e045982 100644 (file)
@@ -1,11 +1,12 @@
 package era.mi.logic.components.gates;
 
 import era.mi.logic.types.BitVector.BitVectorMutator;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class AndGate extends MultiInputGate
 {
-       public AndGate(int processTime, WireEnd out, WireEnd... in)
+       public AndGate(int processTime, ReadWriteEnd out, ReadEnd... in)
        {
                super(processTime, BitVectorMutator::and, out, in);
        }
index 0b4a5d0..dd8a6d6 100644 (file)
@@ -5,16 +5,17 @@ import java.util.List;
 import era.mi.logic.components.BasicComponent;
 import era.mi.logic.types.BitVector.BitVectorMutator;
 import era.mi.logic.types.MutationOperation;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public abstract class MultiInputGate extends BasicComponent
 {
-       protected WireEnd[] in;
-       protected WireEnd out;
+       protected ReadEnd[] in;
+       protected ReadWriteEnd out;
        protected final int length;
        protected MutationOperation op;
 
-       protected MultiInputGate(int processTime, MutationOperation op, WireEnd out, WireEnd... in)
+       protected MultiInputGate(int processTime, MutationOperation op, ReadWriteEnd out, ReadEnd... in)
        {
                super(processTime);
                this.op = op;
@@ -22,7 +23,7 @@ public abstract class MultiInputGate extends BasicComponent
                this.in = in.clone();
                if (in.length < 1)
                        throw new IllegalArgumentException(String.format("Cannot create gate with %d wires.", in.length));
-               for (WireEnd w : in)
+               for (ReadEnd w : in)
                {
                        if (w.length() != length)
                                throw new IllegalArgumentException("All wires connected to the gate must be of uniform length.");
@@ -32,13 +33,13 @@ public abstract class MultiInputGate extends BasicComponent
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(in);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
@@ -47,7 +48,7 @@ public abstract class MultiInputGate extends BasicComponent
        protected void compute()
        {
                BitVectorMutator mutator = BitVectorMutator.empty();
-               for (WireEnd w : in)
+               for (ReadEnd w : in)
                        op.apply(mutator, w.getValues());
                out.feedSignals(mutator.get());
        }
index 1c0d833..150785b 100644 (file)
@@ -3,14 +3,15 @@ package era.mi.logic.components.gates;
 import java.util.List;
 
 import era.mi.logic.components.BasicComponent;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class NotGate extends BasicComponent
 {
-       private WireEnd in;
-       private WireEnd out;
+       private ReadEnd in;
+       private ReadWriteEnd out;
 
-       public NotGate(int processTime, WireEnd in, WireEnd out)
+       public NotGate(int processTime, ReadEnd in, ReadWriteEnd out)
        {
                super(processTime);
                this.in = in;
@@ -24,24 +25,24 @@ public class NotGate extends BasicComponent
                out.feedSignals(in.getValues().not());
        }
 
-       public WireEnd getIn()
+       public ReadEnd getIn()
        {
                return in;
        }
 
-       public WireEnd getOut()
+       public ReadEnd getOut()
        {
                return out;
        }
 
        @Override
-       public List<WireEnd> getAllInputs()
+       public List<ReadEnd> getAllInputs()
        {
                return List.of(in);
        }
 
        @Override
-       public List<WireEnd> getAllOutputs()
+       public List<ReadWriteEnd> getAllOutputs()
        {
                return List.of(out);
        }
index 8c1775f..7450d8f 100644 (file)
@@ -1,11 +1,12 @@
 package era.mi.logic.components.gates;
 
 import era.mi.logic.types.BitVector.BitVectorMutator;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 public class OrGate extends MultiInputGate
 {
-       public OrGate(int processTime, WireEnd out, WireEnd... in)
+       public OrGate(int processTime, ReadWriteEnd out, ReadEnd... in)
        {
                super(processTime, BitVectorMutator::or, out, in);
        }
index 73a2556..7c8d740 100644 (file)
@@ -1,7 +1,8 @@
 package era.mi.logic.components.gates;
 
 import era.mi.logic.types.BitVector.BitVectorMutator;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
 /**
  * Outputs 1 when the number of 1 inputs is odd.
@@ -10,7 +11,7 @@ import era.mi.logic.wires.Wire.WireEnd;
  */
 public class XorGate extends MultiInputGate
 {
-       public XorGate(int processTime, WireEnd out, WireEnd... in)
+       public XorGate(int processTime, ReadWriteEnd out, ReadEnd... in)
        {
                super(processTime, BitVectorMutator::xor, out, in);
        }
index 8a9bc5a..2da847e 100644 (file)
@@ -1,6 +1,8 @@
 package era.mi.logic.tests;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.function.LongConsumer;
 
@@ -20,9 +22,9 @@ 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;
+import era.mi.logic.wires.Wire.ReadEnd;
+import era.mi.logic.wires.Wire.ReadWriteEnd;
 
-@SuppressWarnings("unused")
 class ComponentTest
 {
 
@@ -89,7 +91,7 @@ class ComponentTest
                new TriStateBuffer(1, a.createReadOnlyEnd(), b.createEnd(), en.createReadOnlyEnd());
                new TriStateBuffer(1, b.createReadOnlyEnd(), a.createEnd(), notEn.createReadOnlyEnd());
 
-               WireEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd();
+               ReadWriteEnd enI = en.createEnd(), aI = a.createEnd(), bI = b.createEnd();
                enI.feedSignals(Bit.ONE);
                aI.feedSignals(Bit.ONE);
                bI.feedSignals(Bit.Z);
@@ -119,7 +121,7 @@ class ComponentTest
        {
                Simulation.TIMELINE.reset();
                Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), out = new Wire(4, 1);
-               WireEnd selectIn = select.createEnd();
+               ReadWriteEnd selectIn = select.createEnd();
 
                selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
                a.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
@@ -146,7 +148,7 @@ class ComponentTest
        {
                Simulation.TIMELINE.reset();
                Wire a = new Wire(4, 3), b = new Wire(4, 6), c = new Wire(4, 4), select = new Wire(2, 5), in = new Wire(4, 1);
-               WireEnd selectIn = select.createEnd();
+               ReadWriteEnd selectIn = select.createEnd();
 
                selectIn.feedSignals(Bit.ZERO, Bit.ZERO);
                in.createEnd().feedSignals(Bit.ONE, Bit.ZERO, Bit.ONE, Bit.ZERO);
@@ -240,7 +242,7 @@ class ComponentTest
                new NotGate(1, t2.createReadOnlyEnd(), q.createEnd());
                new NotGate(1, t1.createReadOnlyEnd(), nq.createEnd());
 
-               WireEnd sIn = s.createEnd(), rIn = r.createEnd();
+               ReadWriteEnd sIn = s.createEnd(), rIn = r.createEnd();
 
                sIn.feedSignals(Bit.ONE);
                rIn.feedSignals(Bit.ZERO);
@@ -283,7 +285,7 @@ class ComponentTest
        {
                Simulation.TIMELINE.reset();
                Wire w = new Wire(2, 1);
-               WireEnd wI1 = w.createEnd(), wI2 = w.createEnd();
+               ReadWriteEnd wI1 = w.createEnd(), wI2 = w.createEnd();
                wI1.feedSignals(Bit.ONE, Bit.Z);
                wI2.feedSignals(Bit.Z, Bit.X);
                Simulation.TIMELINE.executeAll();
@@ -298,8 +300,14 @@ class ComponentTest
                assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
 
                wI2.feedSignals(Bit.ONE, Bit.Z);
-               w.addObserver((i, oldValues) -> fail("WireArray notified observer, although value did not change."));
+               ReadEnd rE = w.createReadOnlyEnd();
+               rE.addObserver((i, oldValues) -> fail("WireEnd notified observer, although value did not change."));
                Simulation.TIMELINE.executeAll();
+               rE.close();
+               wI1.feedSignals(Bit.X, Bit.X);
+               Simulation.TIMELINE.executeAll();
+               wI1.addObserver((i, oldValues) -> fail("WireEnd notified observer, although it was closed."));
+               wI1.close();
                assertBitArrayEquals(w.getValues(), Bit.ONE, Bit.Z);
        }
 
@@ -313,9 +321,9 @@ class ComponentTest
                Wire a = new Wire(1, 2);
                Wire b = new Wire(1, 2);
                Wire c = new Wire(1, 2);
-               WireEnd aI = a.createEnd();
-               WireEnd bI = b.createEnd();
-               WireEnd cI = c.createEnd();
+               ReadWriteEnd aI = a.createEnd();
+               ReadWriteEnd bI = b.createEnd();
+               ReadWriteEnd cI = c.createEnd();
 
                TestBitDisplay test = new TestBitDisplay(c.createReadOnlyEnd());
                TestBitDisplay test2 = new TestBitDisplay(a.createReadOnlyEnd());
index cb0494e..82c0854 100644 (file)
@@ -7,12 +7,12 @@ import java.util.function.LongConsumer;
 import era.mi.logic.Simulation;
 import era.mi.logic.components.BitDisplay;
 import era.mi.logic.types.Bit;
-import era.mi.logic.wires.Wire.WireEnd;
+import era.mi.logic.wires.Wire.ReadEnd;
 
 public final class TestBitDisplay extends BitDisplay
 {
 
-       public TestBitDisplay(WireEnd in)
+       public TestBitDisplay(ReadEnd in)
        {
                super(in);
        }
index a7b96ee..9dba1fe 100644 (file)
@@ -1,6 +1,7 @@
 package era.mi.logic.wires;
 
-import static era.mi.logic.types.Bit.*;
+import static era.mi.logic.types.Bit.U;
+import static era.mi.logic.types.Bit.Z;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -20,9 +21,9 @@ public class Wire
 {
        private BitVector values;
        public final int travelTime;
-       private List<WireObserver> observers = new ArrayList<WireObserver>();
+       private List<ReadEnd> attached = new ArrayList<ReadEnd>();
        public final int length;
-       private List<WireEnd> inputs = new ArrayList<WireEnd>();
+       private List<ReadWriteEnd> inputs = new ArrayList<ReadWriteEnd>();
 
        public Wire(int length, int travelTime)
        {
@@ -47,7 +48,7 @@ public class Wire
        private void recalculateMultipleInputs()
        {
                BitVectorMutator mutator = BitVectorMutator.empty();
-               for (WireEnd wireArrayEnd : inputs)
+               for (ReadWriteEnd wireArrayEnd : inputs)
                        mutator.join(wireArrayEnd.getInputValues());
                setNewValues(mutator.get());
        }
@@ -112,7 +113,6 @@ public class Wire
                        case Z:
                        case X:
                                return 0; // TODO: Proper handling for getUnsignedValue(), if not all bits are 1 or 0;
-                       // Random number?
                        case ONE:
                                val |= mask;
                                break;
@@ -170,57 +170,189 @@ public class Wire
         * 
         * @author Fabian Stemmler
         */
-       public boolean addObserver(WireObserver ob)
+       private void attachEnd(ReadEnd end)
        {
-               return observers.add(ob);
+               attached.add(end);
+       }
+
+       private void detachEnd(ReadEnd end)
+       {
+               attached.remove(end);
        }
 
        private void notifyObservers(BitVector oldValues)
        {
-               for (WireObserver o : observers)
-                       o.update(this, oldValues);
+               for (ReadEnd o : attached)
+                       o.update(oldValues);
        }
 
        /**
-        * Create and register a {@link WireEnd} object, which is tied to this {@link Wire}.
+        * Create and register a {@link ReadWriteEnd} object, which is tied to this {@link Wire}. This {@link ReadWriteEnd} can be written to.
         */
-       public WireEnd createEnd()
+       public ReadWriteEnd createEnd()
        {
-               return new WireEnd(false);
+               return new ReadWriteEnd();
        }
 
        /**
-        * Create a {@link WireEnd} object, which is tied to this {@link Wire}. This {@link WireEnd} cannot written to.
+        * Create a {@link ReadEnd} object, which is tied to this {@link Wire}. This {@link ReadEnd} cannot be written to.
         */
-       public WireEnd createReadOnlyEnd()
+       public ReadEnd createReadOnlyEnd()
        {
-               return new WireEnd(true);
+               return new ReadEnd();
        }
 
-       private void registerInput(WireEnd toRegister)
+       private void registerInput(ReadWriteEnd toRegister)
        {
                inputs.add(toRegister);
        }
 
        /**
-        * A {@link WireEnd} feeds a constant signal into the {@link Wire} it is tied to. The combination of all inputs determines the
+        * A {@link ReadEnd} feeds a constant signal into the {@link Wire} it is tied to. The combination of all inputs determines the
         * {@link Wire}s final value. X dominates all other inputs Z does not affect the final value, unless there are no other inputs than Z 0
         * and 1 turn into X when they are mixed
         * 
         * @author Fabian Stemmler
         */
-       public class WireEnd
+       public class ReadEnd
+       {
+               private List<WireObserver> observers = new ArrayList<WireObserver>();
+
+               private ReadEnd()
+               {
+                       super();
+                       Wire.this.attachEnd(this);
+               }
+
+               public void update(BitVector oldValues)
+               {
+                       for (WireObserver ob : observers)
+                               ob.update(this, oldValues);
+               }
+
+               /**
+                * Included for convenient use on {@link Wire}s of length 1.
+                * 
+                * @return The value of bit 0.
+                * 
+                * @author Fabian Stemmler
+                */
+               public Bit getValue()
+               {
+                       return Wire.this.getValue();
+               }
+
+               /**
+                * @param index Index of the requested bit.
+                * @return The value of the indexed bit.
+                * 
+                * @author Fabian Stemmler
+                */
+               public Bit getValue(int index)
+               {
+                       return Wire.this.getValue(index);
+               }
+
+               /**
+                * @param index Index of the requested bit.
+                * @return The value of the indexed bit.
+                * 
+                * @author Fabian Stemmler
+                */
+               public BitVector getValues()
+               {
+                       return Wire.this.getValues();
+               }
+
+               /**
+                * @param start Start of the wanted segment. (inclusive)
+                * @param end   End of the wanted segment. (exclusive)
+                * @return The values of the segment of {@link Bit}s indexed.
+                * 
+                * @author Fabian Stemmler
+                */
+               public BitVector getValues(int start, int end)
+               {
+                       return Wire.this.getValues(start, end);
+               }
+
+               /**
+                * The {@link Wire} is interpreted as an unsigned integer with n bits.
+                * 
+                * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the
+                *         same value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is returned otherwise.
+                * 
+                * @author Fabian Stemmler
+                */
+               public boolean hasNumericValue()
+               {
+                       return Wire.this.hasNumericValue();
+               }
+
+               /**
+                * The {@link Wire} is interpreted as an unsigned integer with n bits.
+                * 
+                * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+                * 
+                * @author Fabian Stemmler
+                */
+               public long getUnsignedValue()
+               {
+                       return Wire.this.getUnsignedValue();
+               }
+
+               /**
+                * The {@link Wire} is interpreted as a signed integer with n bits.
+                * 
+                * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
+                * 
+                * @author Fabian Stemmler
+                */
+               public long getSignedValue()
+               {
+                       return Wire.this.getSignedValue();
+               }
+
+               @Override
+               public String toString()
+               {
+                       return Wire.this.toString();
+               }
+
+               public void close()
+               {
+                       inputs.remove(this);
+                       detachEnd(this);
+                       recalculate();
+               }
+
+               public int length()
+               {
+                       return length;
+               }
+
+               public boolean addObserver(WireObserver ob)
+               {
+                       return observers.add(ob);
+               }
+
+               public Wire getWire()
+               {
+                       return Wire.this;
+               }
+       }
+
+       public class ReadWriteEnd extends ReadEnd
        {
                private boolean open;
                private BitVector inputValues;
 
-               private WireEnd(boolean readOnly)
+               private ReadWriteEnd()
                {
                        super();
-                       open = !readOnly; // TODO: that makes sense, doesn't it?
+                       open = true;
                        initValues();
-                       if (!readOnly)
-                               registerInput(this);
+                       registerInput(this);
                }
 
                private void initValues()
@@ -286,7 +418,7 @@ public class Wire
                }
 
                /**
-                * @return The value (of bit 0) the {@link WireEnd} is currently feeding into the associated {@link Wire}.
+                * @return The value (of bit 0) the {@link ReadEnd} is currently feeding into the associated {@link Wire}.
                 */
                public Bit getInputValue()
                {
@@ -294,7 +426,7 @@ public class Wire
                }
 
                /**
-                * @return The value which the {@link WireEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}.
+                * @return The value which the {@link ReadEnd} is currently feeding into the associated {@link Wire} at the indexed {@link Bit}.
                 */
                public Bit getInputValue(int index)
                {
@@ -302,7 +434,7 @@ public class Wire
                }
 
                /**
-                * @return A copy (safe to modify) of the values the {@link WireEnd} is currently feeding into the associated {@link Wire}.
+                * @return A copy (safe to modify) of the values the {@link ReadEnd} is currently feeding into the associated {@link Wire}.
                 */
                public BitVector getInputValues()
                {
@@ -315,7 +447,7 @@ public class Wire
                }
 
                /**
-                * {@link WireEnd} now feeds Z into the associated {@link Wire}.
+                * {@link ReadEnd} now feeds Z into the associated {@link Wire}.
                 */
                public void clearSignals()
                {
@@ -325,7 +457,7 @@ public class Wire
                public BitVector wireValuesExcludingMe()
                {
                        BitVectorMutator mutator = BitVectorMutator.empty();
-                       for (WireEnd wireEnd : inputs)
+                       for (ReadWriteEnd wireEnd : inputs)
                        {
                                if (wireEnd == this)
                                        continue;
@@ -334,115 +466,10 @@ public class Wire
                        return mutator.get();
                }
 
-               /**
-                * Included for convenient use on {@link Wire}s of length 1.
-                * 
-                * @return The value of bit 0.
-                * 
-                * @author Fabian Stemmler
-                */
-               public Bit getValue()
-               {
-                       return Wire.this.getValue();
-               }
-
-               /**
-                * @param index Index of the requested bit.
-                * @return The value of the indexed bit.
-                * 
-                * @author Fabian Stemmler
-                */
-               public Bit getValue(int index)
-               {
-                       return Wire.this.getValue(index);
-               }
-
-               /**
-                * @param index Index of the requested bit.
-                * @return The value of the indexed bit.
-                * 
-                * @author Fabian Stemmler
-                */
-               public BitVector getValues()
-               {
-                       return Wire.this.getValues();
-               }
-
-               /**
-                * @param start Start of the wanted segment. (inclusive)
-                * @param end   End of the wanted segment. (exclusive)
-                * @return The values of the segment of {@link Bit}s indexed.
-                * 
-                * @author Fabian Stemmler
-                */
-               public BitVector getValues(int start, int end)
-               {
-                       return Wire.this.getValues(start, end);
-               }
-
-               /**
-                * The {@link Wire} is interpreted as an unsigned integer with n bits.
-                * 
-                * @return <code>true</code> if all bits are either <code>Bit.ONE</code> or <code>Bit.ZERO</code> (they do not all have to have the
-                *         same value), not <code>Bit.X</code> or <code>Bit.Z</code>. <code>false</code> is returned otherwise.
-                * 
-                * @author Fabian Stemmler
-                */
-               public boolean hasNumericValue()
-               {
-                       return Wire.this.hasNumericValue();
-               }
-
-               /**
-                * The {@link Wire} is interpreted as an unsigned integer with n bits.
-                * 
-                * @return The unsigned value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
-                * 
-                * @author Fabian Stemmler
-                */
-               public long getUnsignedValue()
-               {
-                       return Wire.this.getUnsignedValue();
-               }
-
-               /**
-                * The {@link Wire} is interpreted as a signed integer with n bits.
-                * 
-                * @return The signed value of the {@link Wire}'s bits, where value 0 corresponds with 2^0, value 1 is 2^1 and so on.
-                * 
-                * @author Fabian Stemmler
-                */
-               public long getSignedValue()
-               {
-                       return Wire.this.getSignedValue();
-               }
-
                @Override
                public String toString()
                {
                        return inputValues.toString();
-                       // return String.format("%s \nFeeding: %s", WireArray.this.toString(), Arrays.toString(inputValues));
-               }
-
-               public void close()
-               {
-                       inputs.remove(this);
-                       open = false;
-               }
-
-               public int length()
-               {
-                       return length;
-               }
-
-               public boolean addObserver(WireObserver ob)
-               {
-                       return Wire.this.addObserver(ob);
-               }
-
-               public Wire getWire()
-               {
-                       return Wire.this;
                }
        }
 
@@ -453,9 +480,9 @@ public class Wire
                // Arrays.toString(values), inputs.stream().map(i -> Arrays.toString(i.inputValues)).reduce((s1, s2) -> s1 + s2)
        }
 
-       public static WireEnd[] extractEnds(Wire[] w)
+       public static ReadEnd[] extractEnds(Wire[] w)
        {
-               WireEnd[] inputs = new WireEnd[w.length];
+               ReadEnd[] inputs = new ReadEnd[w.length];
                for (int i = 0; i < w.length; i++)
                        inputs[i] = w[i].createEnd();
                return inputs;
index 9258e0a..4c4bce0 100644 (file)
@@ -1,8 +1,9 @@
 package era.mi.logic.wires;
 
 import era.mi.logic.types.BitVector;
+import era.mi.logic.wires.Wire.ReadEnd;
 
 public interface WireObserver
 {
-       public void update(Wire initiator, BitVector oldValues);
+       public void update(ReadEnd initiator, BitVector oldValues);
 }