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.LogicModel;
12 import net.mograsim.logic.model.model.LogicModelModifiable;
13 import net.mograsim.logic.model.model.components.ModelComponent;
16 * A connection interface between a ModelComponent and the rest of a LogicModel. Pins usually are created by {@link ModelComponent}s
18 * A pin has a name identifying it. Pin names are unique for a {@link ModelComponent}: Every pin of a {@link ModelComponent} has a different
19 * name, but different {@link ModelComponent}s can have pins with the same name.
21 * @author Daniel Kirschten
26 * The {@link LogicModel} the component this pin belongs to is a part of.
28 private final LogicModelModifiable model;
30 * The {@link ModelComponent} this pin belongs to.
32 public final ModelComponent component;
34 * The name identifying this pin. Is unique for a {@link ModelComponent}.
36 public final String name;
38 * The logical width of this pin. Denotes how many bits this pin consists of.
40 public final int logicWidth;
42 * How this pin is used by the component it belongs to.<br>
43 * Note that this is only a hint.
45 public final PinUsage usage;
48 * The X position of this pin, relative to its component's location.
50 protected double relX;
52 * The Y position of this pin, relative to its component's location.
54 protected double relY;
56 private final List<Consumer<? super Pin>> pinMovedListeners;
57 private final List<Runnable> redrawListeners;
59 // creation and destruction
62 * Creates a new pin. Usually it is not needed to call this constructor manually, as {@link ModelComponent}s create their pins
65 * @author Daniel Kirschten
67 public Pin(LogicModelModifiable model, ModelComponent component, String name, int logicWidth, PinUsage usage, double relX, double relY)
70 this.component = component;
72 this.logicWidth = logicWidth;
73 this.usage = Objects.requireNonNull(usage);
77 this.pinMovedListeners = new ArrayList<>();
78 this.redrawListeners = new ArrayList<>();
80 component.addComponentMovedListener(c -> callPinMovedListeners());
84 * Destroys this pin by removing all wires connected to it from the model the component is a part of.<br>
85 * Don't call this method from application code as it is automatically called in {@link ModelComponent#removePin(String)}.
87 public void destroyed()
89 Set<ModelWire> connectedWires = new HashSet<>();
90 for (ModelWire w : model.getWiresByName().values())
91 if (w.getPin1() == this || w.getPin2() == this)
92 connectedWires.add(w);
93 connectedWires.forEach(model::destroyWire);
96 // "graphical" operations
99 * Returns the X position of this pin relative to the position of its component.
101 * @author Daniel Kirschten
103 public double getRelX()
109 * Returns the Y position of this pin relative to the position of its component.
111 * @author Daniel Kirschten
113 public double getRelY()
119 * Returns the position of this pin relative to the position of its component.
121 * @author Daniel Kirschten
123 public Point getRelPos()
125 return new Point(relX, relY);
129 * Returns the absolute position of this pin.
131 * @author Daniel Kirschten
133 public Point getPos()
135 return new Point(relX + component.getPosX(), relY + component.getPosY());
139 * Sets the position of this pin relative to the position of its component.
141 * @author Daniel Kirschten
143 protected void setRelPos(double relX, double relY)
147 callPinMovedListeners();
148 callRedrawListeners();
154 public void addPinMovedListener (Consumer<? super Pin> listener){pinMovedListeners.add (listener);}
155 public void addRedrawListener (Runnable listener){redrawListeners .add (listener);}
157 public void removePinMovedListener(Consumer<? super Pin> listener){pinMovedListeners.remove(listener);}
158 public void removeRedrawListener (Runnable listener){redrawListeners .remove(listener);}
160 private void callPinMovedListeners() {pinMovedListeners.forEach(l -> l.accept(this));}
161 private void callRedrawListeners () {redrawListeners .forEach(l -> l.run ( ));}
165 public String toString()
167 return "Pin " + name + " of " + component.getName();