Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 131 additions & 75 deletions src/jls/edit/SimpleEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
Expand Down Expand Up @@ -2838,18 +2839,75 @@ private boolean overlap() {
}*/


untouchAll(); // may have moved and stopped touching

// Set is O(n log(n)) to traverse over and doesn't benefit from cache locality.
// we're doing a lot of iterating over the same collection here,
// so it makes sense to use a temporary array for cache locality and O(n) traversal.
Element[] selectedArr = selected.toArray(new Element[selected.size()]);
ArrayList<Element> elementsArr = new ArrayList<Element>(circuit.getElements());
// elementsArr.removeAll(selected);
{
int i = 0;
while (i < elementsArr.size()) {
if (selected.contains(elementsArr.get(i))) {
// "swap" remove - slightly cheaper because we don't care about order
elementsArr.set(i, elementsArr.get(elementsArr.size() - 1));
elementsArr.remove(elementsArr.size() - 1); // pop
// don't increment on erase because [i] now refers to a new element
}
else {
i++;
}
}
}

// bounding box just adds a redundant step if selection is 1
if (selected.size() > 1) {
int xmin = Integer.MAX_VALUE;
int xmax = Integer.MIN_VALUE;
int ymin = Integer.MAX_VALUE;
int ymax = Integer.MIN_VALUE;

// build up a bounding box
for (Element sel : selectedArr) {
xmin = Math.min(xmin, sel.getX());
xmax = Math.max(xmax, sel.getX() + sel.getWidth());
ymin = Math.min(ymin, sel.getY());
ymax = Math.max(ymax, sel.getY() + sel.getHeight());
}

Rectangle bounds = new Rectangle(xmin, ymin, xmax - xmin, ymax - ymin);

// elementsArr.removeIf(el -> !el.isOverlapping(bounds));
{
int i = 0;
while (i < elementsArr.size()) {
if (!elementsArr.get(i).isOverlapping(bounds)) {
// "swap" remove - slightly cheaper because we don't care about order
elementsArr.set(i, elementsArr.get(elementsArr.size() - 1));
elementsArr.remove(elementsArr.size() - 1); // pop
// don't increment on erase because [i] now refers to a new element
}
else {
i++;
}
}
}
}
elementsArr.trimToSize();

// check every element in the selected set
for (Element sel : selected) {
for (Element sel : selectedArr) {

// check against every element in the circuit
for (Element el : circuit.getElements()) {
boolean anyIntersection = false;

// ignore elements in the selected set
if (selected.contains(el))
continue;
// check against every (unselected, bounds-overlapping) element in the circuit
for (Element el : elementsArr) {

// check simple overlap of areas
if (sel.intersects(el)) {
anyIntersection = true;

// no overlap if possible connection,
boolean ok = false;
Expand Down Expand Up @@ -2927,42 +2985,42 @@ else if (el instanceof Wire) {
// selected is not a wire end
else {

// put to wire end
for (Put put : sel.getAllPuts()) {

// if not a wire end, ignore
if (!(el instanceof WireEnd))
continue;
// if element is a wire end, ...
if (el instanceof WireEnd) {
WireEnd end = (WireEnd)el;

// if don't line up, ignore
if (put.getX() != end.getX() || put.getY() != end.getY()) {
continue;
}
// put to wire end
for (Put put : sel.getAllPuts()) {

// if already attached to this wire end, ignore
if (end == put.getWireEnd()) {
ok = true;
continue;
}
// if don't line up, ignore
if (put.getX() != end.getX() || put.getY() != end.getY()) {
continue;
}

// if attached through a single wire, ignore
WireEnd putEnd = put.getWireEnd();
if (putEnd != null &&
putEnd.getOnlyWire().getOtherEnd(putEnd) == end) {
ok = true;
continue;
}
// if already attached to this wire end, ignore
if (end == put.getWireEnd()) {
ok = true;
continue;
}

// if cannot connect, return
if (!canConnect(end,put)) {
untouchAll();
return true;
}
// if attached through a single wire, ignore
WireEnd putEnd = put.getWireEnd();
if (putEnd != null &&
putEnd.getOnlyWire().getOtherEnd(putEnd) == end) {
ok = true;
continue;
}

end.setTouching(true);
put.setTouching(true);
ok = true;
// if cannot connect, return
if (!canConnect(end,put)) {
untouchAll();
return true;
}

end.setTouching(true);
put.setTouching(true);
ok = true;
}
}
}
if (!ok) {
Expand All @@ -2971,52 +3029,50 @@ else if (el instanceof Wire) {
return true;
}
}
}

// no intersection, but wires may be overlapping wire ends
// or puts might line up
else {
// no intersection, but wires may be overlapping wire ends
// or puts might line up
if (!anyIntersection) {

// see if wires connected to a wire end dragged onto wire ends
if (sel instanceof WireEnd) {
WireEnd end = (WireEnd)sel;
for (Wire wire : end.getWires()) {
for (Element elm : circuit.getElements()) {
if (sel == elm)
continue;
if (!(elm instanceof WireEnd)) {
continue;
}
WireEnd otherEnd = (WireEnd)elm;
if (wire.touches(otherEnd)) {
overlapMessage = "overlap";
untouchAll();
return true;
}
// see if wires connected to a wire end dragged onto wire ends
if (sel instanceof WireEnd) {
WireEnd end = (WireEnd)sel;
for (Wire wire : end.getWires()) {
for (Element el : elementsArr) {
if (!(el instanceof WireEnd)) {
continue;
}
WireEnd otherEnd = (WireEnd)el;
if (wire.touches(otherEnd)) {
overlapMessage = "overlap";
untouchAll();
return true;
}
}
}
}

// see if wires connected to puts dragged onto wire ends
for (Put p : sel.getAllPuts()) {
if (p.isAttached()) {
Wire wire = p.getWireEnd().getOnlyWire();
for (Element elm : circuit.getElements()) {
if (sel == elm)
continue;
if (!(elm instanceof WireEnd)) {
continue;
}
WireEnd otherEnd = (WireEnd)elm;
if (wire.touches(otherEnd)) {
overlapMessage = "overlap";
untouchAll();
return true;
}
// see if wires connected to puts dragged onto wire ends
for (Put p : sel.getAllPuts()) {
if (p.isAttached()) {
Wire wire = p.getWireEnd().getOnlyWire();
for (Element el : elementsArr) {
if (!(el instanceof WireEnd)) {
continue;
}
WireEnd otherEnd = (WireEnd)el;
if (wire.touches(otherEnd)) {
overlapMessage = "overlap";
untouchAll();
return true;
}
}
}
}

// check all put combinations
// check all put combinations
for (Element el : elementsArr) {
for (Put p1 : sel.getAllPuts()) {
for (Put p2 : el.getAllPuts()) {

Expand All @@ -3028,7 +3084,7 @@ else if (el instanceof Wire) {
// ignore overlaps on already connected puts
WireEnd end1 = p1.getWireEnd();
WireEnd end2 = p2.getWireEnd();
if (end1 != null && end2 != null &&
if (end1 != null && end2 != null &&
end1.getOnlyWire().getOtherEnd(end1) == end2) {
continue;
}
Expand All @@ -3047,8 +3103,8 @@ else if (el instanceof Wire) {
}
}
}
repaint();
return false;
repaint();
return false;
} // end of overlap method

/**
Expand Down
33 changes: 33 additions & 0 deletions src/jls/elem/Element.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ public int getY() {

return y;
} // end of getY method

/**
* Get width of this element.
*
* @return the width.
*/
public int getWidth() {

return width;
} // end of getWidth method

/**
* Get height of this element.
*
* @return the height.
*/
public int getHeight() {

return height;
} // end of getHeight method

/**
* Get the trace position of this element.
Expand Down Expand Up @@ -328,6 +348,19 @@ public boolean isInside(Rectangle rect) {
return rect.contains(me);
} // end of isInside method

/**
* See if this element is intersecting a given rectangle.
*
* @param rect The given rectangle.
*
* @return true if the element is intersecting, false if not.
*/
public boolean isOverlapping(Rectangle rect) {

Rectangle me = getRect();
return rect.intersects(me);
} // end of isOverlapping method

/**
* Set/reset highlight.
*
Expand Down