1 package net.mograsim.logic.model.model.wires;
3 import java.util.ArrayList;
4 import java.util.HashSet;
6 import java.util.Objects;
8 import java.util.function.Consumer;
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;
15 * A connection interface between a ModelComponent and the rest of a LogicModel. Pins usually are created by {@link ModelComponent}s
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.
20 * @author Daniel Kirschten
25 * The {@link LogicModel} the component this pin belongs to is a part of.
27 private final LogicModelModifiable model;
29 * The {@link ModelComponent} this pin belongs to.
31 public final ModelComponent component;
33 * The name identifying this pin. Is unique for a {@link ModelComponent}.
35 public final String name;
37 * The logical width of this pin. Denotes how many bits this pin consists of.
39 public final int logicWidth;
41 * How this pin is used by the component it belongs to.<br>
42 * Note that this is only a hint.
44 public final PinUsage usage;
47 * The X position of this pin, relative to its component's location.
49 protected double relX;
51 * The Y position of this pin, relative to its component's location.
53 protected double relY;
55 private final List<Consumer<? super Pin>> pinMovedListeners;
56 private final List<Runnable> redrawListeners;
58 // creation and destruction
61 * Creates a new pin. Usually it is not needed to call this constructor manually, as {@link ModelComponent}s create their pins
64 * @author Daniel Kirschten
66 public Pin(LogicModelModifiable model, ModelComponent component, String name, int logicWidth, PinUsage usage, double relX, double relY)
69 this.component = component;
71 this.logicWidth = logicWidth;
72 this.usage = Objects.requireNonNull(usage);
76 this.pinMovedListeners = new ArrayList<>();
77 this.redrawListeners = new ArrayList<>();
79 component.addComponentMovedListener(c -> callPinMovedListeners());
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)}.
86 public void destroyed()
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);
95 // "graphical" operations
98 * Returns the X position of this pin relative to the position of its component.
100 * @author Daniel Kirschten
102 public double getRelX()
108 * Returns the Y position of this pin relative to the position of its component.
110 * @author Daniel Kirschten
112 public double getRelY()
118 * Returns the position of this pin relative to the position of its component.
120 * @author Daniel Kirschten
122 public Point getRelPos()
124 return new Point(relX, relY);
128 * Returns the absolute position of this pin.
130 * @author Daniel Kirschten
132 public Point getPos()
134 return new Point(relX + component.getPosX(), relY + component.getPosY());
138 * Sets the position of this pin relative to the position of its component.
140 * @author Daniel Kirschten
142 protected void setRelPos(double relX, double relY)
146 callPinMovedListeners();
147 callRedrawListeners();
153 public void addPinMovedListener (Consumer<? super Pin> listener){pinMovedListeners.add (listener);}
154 public void addRedrawListener (Runnable listener){redrawListeners .add (listener);}
156 public void removePinMovedListener(Consumer<? super Pin> listener){pinMovedListeners.remove(listener);}
157 public void removeRedrawListener (Runnable listener){redrawListeners .remove(listener);}
159 private void callPinMovedListeners() {pinMovedListeners.forEach(l -> l.accept(this));}
160 private void callRedrawListeners () {redrawListeners .forEach(l -> l.run ( ));}
164 public String toString()
166 return "Pin " + name + " of " + component.getName();