The final restructured version for automatic build using maven tycho
[Mograsim.git] / plugins / 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.HashSet;
5 import java.util.List;
6 import java.util.Objects;
7 import java.util.Set;
8 import java.util.function.Consumer;
9
10 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
11 import net.mograsim.logic.model.model.LogicModelModifiable;
12 import net.mograsim.logic.model.model.components.ModelComponent;
13
14 /**
15  * A connection interface between a ModelComponent and the rest of a LogicModel. Pins usually are created by {@link ModelComponent}s
16  * themselves. <br>
17  * A pin has a name identifying it. Pin names are unique for a {@link ModelComponent}: Every pin of a {@link ModelComponent} has a different
18  * name, but different {@link ModelComponent}s can have pins with the same name.
19  * 
20  * @author Daniel Kirschten
21  */
22 public class Pin
23 {
24         /**
25          * The {@link LogicModel} the component this pin belongs to is a part of.
26          */
27         private final LogicModelModifiable model;
28         /**
29          * The {@link ModelComponent} this pin belongs to.
30          */
31         public final ModelComponent component;
32         /**
33          * The name identifying this pin. Is unique for a {@link ModelComponent}.
34          */
35         public final String name;
36         /**
37          * The logical width of this pin. Denotes how many bits this pin consists of.
38          */
39         public final int logicWidth;
40         /**
41          * How this pin is used by the component it belongs to.<br>
42          * Note that this is only a hint.
43          */
44         public final PinUsage usage;
45
46         /**
47          * The X position of this pin, relative to its component's location.
48          */
49         protected double relX;
50         /**
51          * The Y position of this pin, relative to its component's location.
52          */
53         protected double relY;
54
55         private final List<Consumer<? super Pin>> pinMovedListeners;
56         private final List<Runnable> redrawListeners;
57
58         // creation and destruction
59
60         /**
61          * Creates a new pin. Usually it is not needed to call this constructor manually, as {@link ModelComponent}s create their pins
62          * themselves.
63          * 
64          * @author Daniel Kirschten
65          */
66         public Pin(LogicModelModifiable model, ModelComponent component, String name, int logicWidth, PinUsage usage, double relX, double relY)
67         {
68                 this.model = model;
69                 this.component = component;
70                 this.name = name;
71                 this.logicWidth = logicWidth;
72                 this.usage = Objects.requireNonNull(usage);
73                 this.relX = relX;
74                 this.relY = relY;
75
76                 this.pinMovedListeners = new ArrayList<>();
77                 this.redrawListeners = new ArrayList<>();
78
79                 component.addComponentMovedListener(c -> callPinMovedListeners());
80         }
81
82         /**
83          * Destroys this pin by removing all wires connected to it from the model the component is a part of.<br>
84          * Don't call this method from application code as it is automatically called in {@link ModelComponent#removePin(String)}.
85          */
86         public void destroyed()
87         {
88                 Set<ModelWire> connectedWires = new HashSet<>();
89                 for (ModelWire w : model.getWiresByName().values())
90                         if (w.getPin1() == this || w.getPin2() == this)
91                                 connectedWires.add(w);
92                 connectedWires.forEach(model::destroyWire);
93         }
94
95         // "graphical" operations
96
97         /**
98          * Returns the X position of this pin relative to the position of its component.
99          * 
100          * @author Daniel Kirschten
101          */
102         public double getRelX()
103         {
104                 return relX;
105         }
106
107         /**
108          * Returns the Y position of this pin relative to the position of its component.
109          * 
110          * @author Daniel Kirschten
111          */
112         public double getRelY()
113         {
114                 return relY;
115         }
116
117         /**
118          * Returns the position of this pin relative to the position of its component.
119          * 
120          * @author Daniel Kirschten
121          */
122         public Point getRelPos()
123         {
124                 return new Point(relX, relY);
125         }
126
127         /**
128          * Returns the absolute position of this pin.
129          * 
130          * @author Daniel Kirschten
131          */
132         public Point getPos()
133         {
134                 return new Point(relX + component.getPosX(), relY + component.getPosY());
135         }
136
137         /**
138          * Sets the position of this pin relative to the position of its component.
139          * 
140          * @author Daniel Kirschten
141          */
142         protected void setRelPos(double relX, double relY)
143         {
144                 this.relX = relX;
145                 this.relY = relY;
146                 callPinMovedListeners();
147                 callRedrawListeners();
148         }
149
150         // listeners
151
152         // @formatter:off
153         public void addPinMovedListener   (Consumer<? super Pin> listener){pinMovedListeners.add   (listener);}
154         public void addRedrawListener     (Runnable              listener){redrawListeners  .add   (listener);}
155
156         public void removePinMovedListener(Consumer<? super Pin> listener){pinMovedListeners.remove(listener);}
157         public void removeRedrawListener  (Runnable              listener){redrawListeners  .remove(listener);}
158
159         private void callPinMovedListeners() {pinMovedListeners.forEach(l -> l.accept(this));}
160         private void callRedrawListeners  () {redrawListeners  .forEach(l -> l.run   (    ));}
161         // @formatter:on
162
163         @Override
164         public String toString()
165         {
166                 return "Pin " + name + " of " + component.getName();
167         }
168 }