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