WireArray(Input) is now Wire(End); all in-/outputs are now WireEnds
[Mograsim.git] / era.mi / src / era / mi / logic / components / Merger.java
1 package era.mi.logic.components;
2
3 import java.util.Arrays;
4 import java.util.Collections;
5 import java.util.List;
6
7 import era.mi.logic.Bit;
8 import era.mi.logic.wires.Wire;
9 import era.mi.logic.wires.Wire.WireEnd;
10 import era.mi.logic.wires.WireArrayObserver;
11
12 public class Merger implements WireArrayObserver, Component
13 {
14         private WireEnd out;
15         private WireEnd[] inputs;
16         private int[] beginningIndex;
17
18         /**
19          * 
20          * @param union  The output of merging n {@link Wire}s into one. Must have length = a1.length() + a2.length() + ... + an.length().
21          * @param inputs The inputs to be merged into the union
22          */
23         public Merger(WireEnd union, WireEnd... inputs)
24         {
25                 this.inputs = inputs;
26                 this.out = union;
27                 this.beginningIndex = new int[inputs.length];
28
29                 int length = 0;
30                 for (int i = 0; i < inputs.length; i++)
31                 {
32                         beginningIndex[i] = length;
33                         length += inputs[i].length();
34                         inputs[i].addObserver(this);
35                 }
36
37                 if (length != union.length())
38                         throw new IllegalArgumentException(
39                                         "The output of merging n WireArrays into one must have length = a1.length() + a2.length() + ... + an.length().");
40         }
41
42         public WireEnd getInput(int index)
43         {
44                 return inputs[index];
45         }
46
47         public WireEnd getUnion()
48         {
49                 return out;
50         }
51
52         @Override
53         public void update(Wire initiator, Bit[] oldValues)
54         {
55                 int index = find(initiator);
56                 int beginning = beginningIndex[index];
57                 out.feedSignals(beginning, inputs[index].getValues());
58         }
59
60         private int find(Wire w)
61         {
62                 for (int i = 0; i < inputs.length; i++)
63                         if (inputs[i].getWire() == w)
64                                 return i;
65                 return -1;
66         }
67
68         public WireEnd[] getInputs()
69         {
70                 return inputs.clone();
71         }
72
73         @Override
74         public List<WireEnd> getAllInputs()
75         {
76                 return Collections.unmodifiableList(Arrays.asList(inputs));
77         }
78
79         @Override
80         public List<WireEnd> getAllOutputs()
81         {
82                 return Collections.unmodifiableList(Arrays.asList(out));
83         }
84 }