+ public class ReadWriteEnd extends ReadEnd
+ {
+ private boolean open;
+ private BitVector inputValues;
+
+ private ReadWriteEnd()
+ {
+ super();
+ open = true;
+ initValues();
+ registerInput(this);
+ }
+
+ private void initValues()
+ {
+ inputValues = U.toVector(length);
+ }
+
+ /**
+ * Sets the wires values. This takes up time, as specified by the {@link Wire}s travel time.
+ *
+ * @param newValues The new values the wires should take on.
+ *
+ * @author Fabian Stemmler
+ */
+ public void feedSignals(Bit... newValues)
+ {
+ 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));
+ 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 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, BitVector bitVector)
+ {
+ if (!open)
+ throw new RuntimeException("Attempted to write to closed WireArrayEnd.");
+ Simulation.TIMELINE.addEvent(e -> setValues(startingBit, bitVector), travelTime);
+ }
+
+ private void setValues(int startingBit, BitVector newValues)
+ {
+ // index check covered in equals
+ if (!inputValues.equalsWithOffset(newValues, startingBit))
+ {
+ 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 ReadEnd} is currently feeding into the associated {@link Wire}.
+ */
+ public Bit getInputValue()
+ {
+ return getInputValue(0);
+ }
+
+ /**
+ * @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)
+ {
+ return inputValues.getBit(index);
+ }
+
+ /**
+ * @return A copy (safe to modify) of the values the {@link ReadEnd} is currently feeding into the associated {@link Wire}.
+ */
+ public BitVector getInputValues()
+ {
+ return getInputValues(0, length);
+ }
+
+ public BitVector getInputValues(int start, int end)
+ {
+ return inputValues.subVector(start, end);
+ }
+
+ /**
+ * {@link ReadEnd} now feeds Z into the associated {@link Wire}.
+ */
+ public void clearSignals()
+ {
+ feedSignals(Z.toVector(length));
+ }
+
+ public BitVector wireValuesExcludingMe()
+ {
+ BitVectorMutator mutator = BitVectorMutator.empty();
+ for (ReadWriteEnd wireEnd : inputs)
+ {
+ if (wireEnd == this)
+ continue;
+ mutator.join(wireEnd.inputValues);
+ }
+ return mutator.get();
+ }
+
+ @Override
+ public String toString()
+ {
+ return inputValues.toString();
+ }
+ }
+