* The model this wire is a part of.
*/
private final ViewModelModifiable model;
+ /**
+ * The name of this wire. Is unique for all wires in its model.
+ */
+ public final String name;
/**
* The logical width of this wire. Is equal to the logical with of {@link #pin1} and {@link #pin2}.
*/
*/
private double[] effectivePath;
- private final List<Runnable> redrawListeners;
private final List<Consumer<GUIWire>> pathChangedListeners;
/**
// creation and destruction
/**
- * Creates a new {@link GUIWire} with automatic interpolation.
+ * Creates a new {@link GUIWire} with automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, WireCrossPoint pin1, WireCrossPoint pin2)
{
- this(model, pin1, pin2, (Point[]) null);
+ this(model, null, pin1, pin2);
}
/**
- * Creates a new {@link GUIWire} with automatic interpolation.
+ * Creates a new {@link GUIWire} with automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, WireCrossPoint pin1, Pin pin2)
{
- this(model, pin1, pin2, (Point[]) null);
+ this(model, null, pin1, pin2);
}
/**
- * Creates a new {@link GUIWire} with automatic interpolation.
+ * Creates a new {@link GUIWire} with automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, Pin pin1, WireCrossPoint pin2)
{
- this(model, pin1, pin2, (Point[]) null);
+ this(model, null, pin1, pin2);
}
/**
- * Creates a new {@link GUIWire} with automatic interpolation.
+ * Creates a new {@link GUIWire} with automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, Pin pin1, Pin pin2)
{
- this(model, pin1, pin2, (Point[]) null);
+ this(model, null, pin1, pin2);
}
/**
- * Creates a new {@link GUIWire} without automatic interpolation.
+ * Creates a new {@link GUIWire} without automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, WireCrossPoint pin1, WireCrossPoint pin2, Point... path)
{
- this(model, pin1.getPin(), pin2.getPin(), path);
+ this(model, null, pin1, pin2, path);
}
/**
- * Creates a new {@link GUIWire} without automatic interpolation.
+ * Creates a new {@link GUIWire} without automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, WireCrossPoint pin1, Pin pin2, Point... path)
{
- this(model, pin1.getPin(), pin2, path);
+ this(model, null, pin1, pin2, path);
}
/**
- * Creates a new {@link GUIWire} without automatic interpolation.
+ * Creates a new {@link GUIWire} without automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, Pin pin1, WireCrossPoint pin2, Point... path)
{
- this(model, pin1, pin2.getPin(), path);
+ this(model, null, pin1, pin2, path);
}
/**
- * Creates a new {@link GUIWire} without automatic interpolation.
+ * Creates a new {@link GUIWire} without automatic interpolation and using the default name.
*
* @author Daniel Kirschten
*/
public GUIWire(ViewModelModifiable model, Pin pin1, Pin pin2, Point... path)
+ {
+ this(model, null, pin1, pin2, path);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} with automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, WireCrossPoint pin1, WireCrossPoint pin2)
+ {
+ this(model, name, pin1, pin2, (Point[]) null);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} with automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, WireCrossPoint pin1, Pin pin2)
+ {
+ this(model, name, pin1, pin2, (Point[]) null);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} with automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, Pin pin1, WireCrossPoint pin2)
+ {
+ this(model, name, pin1, pin2, (Point[]) null);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} with automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, Pin pin1, Pin pin2)
+ {
+ this(model, name, pin1, pin2, (Point[]) null);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} without automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, WireCrossPoint pin1, WireCrossPoint pin2, Point... path)
+ {
+ this(model, name, pin1.getPin(), pin2.getPin(), path);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} without automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, WireCrossPoint pin1, Pin pin2, Point... path)
+ {
+ this(model, name, pin1.getPin(), pin2, path);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} without automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, Pin pin1, WireCrossPoint pin2, Point... path)
+ {
+ this(model, name, pin1, pin2.getPin(), path);
+ }
+
+ /**
+ * Creates a new {@link GUIWire} without automatic interpolation.
+ *
+ * @author Daniel Kirschten
+ */
+ public GUIWire(ViewModelModifiable model, String name, Pin pin1, Pin pin2, Point... path)
{
this.model = model;
+ this.name = name == null ? model.getDefaultWireName() : name;
this.logicWidth = pin1.logicWidth;
if (pin2.logicWidth != pin1.logicWidth)
throw new IllegalArgumentException("Can't connect pins of different logic width");
this.path = path == null ? null : Arrays.copyOf(path, path.length);
this.bounds = new Rectangle(0, 0, -1, -1);
- redrawListeners = new ArrayList<>();
pathChangedListeners = new ArrayList<>();
- logicObs = (i) -> callRedrawListeners();
+ logicObs = (i) -> model.requestRedraw();
pin1.addPinMovedListener(p -> pinMoved());
pin2.addPinMovedListener(p -> pinMoved());
recalculateEffectivePath();
- model.wireCreated(this);
+ model.wireCreated(this, this::destroyed);
}
/**
- * Destroys this wire. This method implicitly calls {@link ViewModelModifiable#wireDestroyed(GUIWire) wireDestroyed()} for the model
- * this component is a part of.
+ * Destroys this wire. This method is called from {@link ViewModelModifiable#wireDestroyed(GUIWire) wireDestroyed()} of the model this
+ * wire is a part of.
*
* @author Daniel Kirschten
*/
- public void destroy()
+ private void destroyed()
{
- model.wireDestroyed(this);
+ // nothing to do
}
// pins
private void pinMoved()
{
recalculateEffectivePath();
- callRedrawListeners();
+ model.requestRedraw();
}
// "graphical" operations
*/
public void render(GeneralGC gc)
{
+ // TODO maybe make wires with logicWidth!=1 thicker? Maybe make thickness selectable?
ColorDefinition wireColor = BitVectorFormatter.formatAsColor(end);
if (wireColor != null)
gc.setForeground(ColorManager.current().toColor(wireColor));
this.path = deepPathCopy(path);
recalculateEffectivePath();
callPathChangedListeners();
- callRedrawListeners();
+ model.requestRedraw();
}
public Point getPathPoint(int index)
path[index] = pointCopy(p);
recalculateEffectivePath();
callPathChangedListeners();
- callRedrawListeners();
+ model.requestRedraw();
}
public void insertPathPoint(Point p, int index)
System.arraycopy(oldPath, index, path, index + 1, oldPath.length - index);
path[index] = pointCopy(p);
}
+ recalculateEffectivePath();
+ callPathChangedListeners();
}
public void removePathPoint(int index)
if (index < oldPath.length - 1)
System.arraycopy(oldPath, index + 1, path, index, oldPath.length - index - 1);
}
+ recalculateEffectivePath();
+ callPathChangedListeners();
}
public double[] getEffectivePath()
// listeners
// @formatter:off
- public void addRedrawListener (Runnable listener) {redrawListeners .add (listener);}
public void addPathChangedListener (Consumer<GUIWire> listener) {pathChangedListeners.add (listener);}
- public void removeRedrawListener (Runnable listener) {redrawListeners .remove(listener);}
public void removePathChangedListener(Consumer<GUIWire> listener) {pathChangedListeners.remove(listener);}
- private void callRedrawListeners () {redrawListeners .forEach(l -> l.run ( ));}
private void callPathChangedListeners() {pathChangedListeners.forEach(l -> l.accept(this));}
// @formatter:on