Merge branch 'development' of
[Mograsim.git] / LogicUI / src / era / mi / gui / model / wires / GUIWire.java
1 package era.mi.gui.model.wires;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.function.Consumer;
6
7 import era.mi.gui.ColorHelper;
8 import era.mi.gui.model.ViewModel;
9 import era.mi.logic.types.BitVectorFormatter;
10 import era.mi.logic.wires.Wire.ReadEnd;
11 import net.haspamelodica.swt.helper.gcs.GeneralGC;
12 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
13
14 public class GUIWire
15 {
16         private final ViewModel model;
17         private Pin pin1;
18         private Pin pin2;
19         private double[] path;
20
21         private final List<Consumer<? super GUIWire>> wireChangedListeners;
22
23         private ReadEnd end;
24
25         public GUIWire(ViewModel model, Pin pin1, Pin pin2, Point... path)
26         {
27                 this.model = model;
28                 this.path = new double[path.length * 2 + 4];
29                 for (int srcI = 0, dstI = 2; srcI < path.length; srcI++, dstI += 2)
30                 {
31                         this.path[dstI + 0] = path[srcI].x;
32                         this.path[dstI + 1] = path[srcI].y;
33                 }
34
35                 this.pin1 = pin1;
36                 this.pin2 = pin2;
37
38                 wireChangedListeners = new ArrayList<>();
39
40                 pin1.addPinMovedListener(p -> pin1Moved());
41                 pin2.addPinMovedListener(p -> pin2Moved());
42                 pin1Moved();
43                 pin2Moved();
44
45                 model.wireCreated(this);
46         }
47
48         private void pin1Moved()
49         {
50                 Point pos = pin1.getPos();
51                 this.path[0] = pos.x;
52                 this.path[1] = pos.y;
53         }
54
55         private void pin2Moved()
56         {
57                 Point pos = pin2.getPos();
58                 this.path[this.path.length - 2] = pos.x;
59                 this.path[this.path.length - 1] = pos.y;
60         }
61
62         public void destroy()
63         {
64                 model.wireDestroyed(this);
65         }
66
67         public void render(GeneralGC gc)
68         {
69                 ColorHelper.executeWithDifferentForeground(gc, BitVectorFormatter.formatAsColor(end), () -> gc.drawPolyline(path));
70         }
71
72         public void setLogicModelBinding(ReadEnd end)
73         {
74                 this.end = end;
75                 end.addObserver((i, o) -> callWireChangedListeners());
76         }
77
78         // @formatter:off
79         public void addWireChangedListener   (Consumer<? super GUIWire> listener) {wireChangedListeners.add   (listener);}
80
81         public void removeWireChangedListener(Consumer<? super GUIWire> listener) {wireChangedListeners.remove(listener);}
82
83         private void callWireChangedListeners() {wireChangedListeners.forEach(l -> l.accept(this));}
84         // @formatter:on
85
86 }