Merge branch 'development' of https://gitlab.lrz.de/lrr-tum/students/eragp-misim...
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / wires / Pin.java
1 package net.mograsim.logic.model.model.wires;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Objects;
6 import java.util.function.Consumer;
7
8 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
9 import net.mograsim.logic.model.model.components.GUIComponent;
10
11 /**
12  * A connection interface between a GUIComponent and the rest of a ViewModel. Pins usually are created by {@link GUIComponent}s themselves.
13  * <br>
14  * A pin has a name identifying it. Pin names are unique for a {@link GUIComponent}: Every pin of a {@link GUIComponent} has a different
15  * name, but different {@link GUIComponent}s can have pins with the same name.
16  * 
17  * @author Daniel Kirschten
18  */
19 public class Pin
20 {
21         /**
22          * The {@link GUIComponent} this pin belongs to.
23          */
24         public final GUIComponent component;
25         /**
26          * The name identifying this pin. Is unique for a {@link GUIComponent}.
27          */
28         public final String name;
29         /**
30          * The logical width of this pin. Denotes how many bits this pin consists of.
31          */
32         public final int logicWidth;
33         /**
34          * How this pin is used by the component it belongs to.<br>
35          * Note that this is only a hint.
36          */
37         public final PinUsage usage;
38
39         /**
40          * The X position of this pin, relative to its component's location.
41          */
42         protected double relX;
43         /**
44          * The Y position of this pin, relative to its component's location.
45          */
46         protected double relY;
47
48         private final List<Consumer<? super Pin>> pinMovedListeners;
49         private final List<Runnable> redrawListeners;
50
51         // creation and destruction
52
53         /**
54          * Creates a new pin. Usually it is not needed to call this constructor manually, as {@link GUIComponent}s create their pins themselves.
55          * 
56          * @author Daniel Kirschten
57          */
58         public Pin(GUIComponent component, String name, int logicWidth, PinUsage usage, double relX, double relY)
59         {
60                 this.component = component;
61                 this.name = name;
62                 this.logicWidth = logicWidth;
63                 this.usage = Objects.requireNonNull(usage);
64                 this.relX = relX;
65                 this.relY = relY;
66
67                 this.pinMovedListeners = new ArrayList<>();
68                 this.redrawListeners = new ArrayList<>();
69
70                 component.addComponentMovedListener(c -> callPinMovedListeners());
71         }
72
73         // "graphical" operations
74
75         /**
76          * Returns the X position of this pin relative to the position of its component.
77          * 
78          * @author Daniel Kirschten
79          */
80         public double getRelX()
81         {
82                 return relX;
83         }
84
85         /**
86          * Returns the Y position of this pin relative to the position of its component.
87          * 
88          * @author Daniel Kirschten
89          */
90         public double getRelY()
91         {
92                 return relY;
93         }
94
95         /**
96          * Returns the position of this pin relative to the position of its component.
97          * 
98          * @author Daniel Kirschten
99          */
100         public Point getRelPos()
101         {
102                 return new Point(relX, relY);
103         }
104
105         /**
106          * Returns the absolute position of this pin.
107          * 
108          * @author Daniel Kirschten
109          */
110         public Point getPos()
111         {
112                 return new Point(relX + component.getPosX(), relY + component.getPosY());
113         }
114
115         /**
116          * Sets the position of this pin relative to the position of its component.
117          * 
118          * @author Daniel Kirschten
119          */
120         protected void setRelPos(double relX, double relY)
121         {
122                 this.relX = relX;
123                 this.relY = relY;
124                 callPinMovedListeners();
125                 callRedrawListeners();
126         }
127
128         // listeners
129
130         // @formatter:off
131         public void addPinMovedListener   (Consumer<? super Pin> listener){pinMovedListeners.add   (listener);}
132         public void addRedrawListener     (Runnable              listener){redrawListeners  .add   (listener);}
133
134         public void removePinMovedListener(Consumer<? super Pin> listener){pinMovedListeners.remove(listener);}
135         public void removeRedrawListener  (Runnable              listener){redrawListeners  .remove(listener);}
136
137         private void callPinMovedListeners() {pinMovedListeners.forEach(l -> l.accept(this));}
138         private void callRedrawListeners  () {redrawListeners  .forEach(l -> l.run   (    ));}
139         // @formatter:on
140
141         @Override
142         public String toString()
143         {
144                 return "Pin [" + name + ", point=" + getPos() + "]";
145         }
146 }