reintroduced Wire for performance

This commit is contained in:
Patrick Haßel 2024-05-17 10:38:01 +02:00
parent 3e7f0b5e73
commit 8a190cb755
35 changed files with 132 additions and 102 deletions

View File

@ -1,11 +1,12 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.PartDto;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.PartDto;
import de.ph87.electro.circuit.part.parts.*;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import java.awt.*;
@ -23,14 +24,21 @@ public class Circuit {
private final List<Part> parts = new ArrayList<>();
private final List<Wire> wires = new ArrayList<>();
public Circuit(final CircuitDto dto) {
final List<Junction> junctions = new ArrayList<>();
for (PartDto partDto : dto.getParts()) {
final Part part = Part.of(partDto);
partAdd(part);
junctions.addAll(part.getJunctions());
if (!isFree(part.getPosition())) {
throw new RuntimeException();
}
parts.add(part);
}
for (final WireDto wire : dto.getWires()) {
final Junction a = findJunctionByUuid(wire.getA()).orElseThrow();
final Junction b = findJunctionByUuid(wire.getB()).orElseThrow();
wires.add(new Wire(a, b));
}
parts.forEach(part -> part.link(junctions));
}
public PartBattery addBattery(final String name, final int x, final int y, final Orientation orientation, final double voltage) {
@ -64,8 +72,7 @@ public class Circuit {
}
public void connect(final Junction a, final Junction b) {
a.getDestinations().add(b);
b.getDestinations().add(a);
wires.add(new Wire(a, b));
evaluateAndRender();
}
@ -79,18 +86,8 @@ public class Circuit {
return parts.stream().filter(part -> part instanceof PartBattery).map(part -> (PartBattery) part);
}
public List<Wire> getWires() {
final List<Wire> wires = new ArrayList<>();
for (final Part part : parts) {
for (final Junction junction : part.getJunctions()) {
for (final Junction destination : junction.getDestinations()) {
if (wires.stream().noneMatch(wire -> wire.matches(junction, destination))) {
wires.add(new Wire(junction, destination));
}
}
}
}
return wires;
public Stream<Wire> streamWires() {
return wires.stream();
}
public void partAdd(final Part part) {
@ -133,8 +130,22 @@ public class Circuit {
return findPart(point).flatMap(part -> part.findJunction(point));
}
public Optional<Junction> findJunctionByUuid(@NonNull final String junctionUuid) {
return parts.stream().map(part -> part.findJunctionByUuid(junctionUuid)).filter(Optional::isPresent).map(Optional::get).findFirst();
}
public Optional<Wire> findWireByPoint(final Point point) {
return getWires().stream().filter(wire -> wire.intersects(point)).findFirst();
return wires.stream().filter(wire -> wire.intersects(point)).findFirst();
}
public void removeWire(final Wire wire) {
if (!wires.contains(wire)) {
throw new RuntimeException();
}
wires.remove(wire);
wire.getA().getWires().remove(wire);
wire.getB().getWires().remove(wire);
evaluateAndRender();
}
}

View File

@ -14,8 +14,11 @@ public class CircuitDto {
private List<PartDto> parts;
private List<WireDto> wires;
public CircuitDto(final Circuit circuit) {
this.parts = circuit.streamParts().map(PartDto::of).toList();
this.wires = circuit.streamWires().map(WireDto::new).toList();
}
}

View File

@ -51,14 +51,14 @@ public class CircuitPanel extends JPanel {
}
private void drawWires(final Graphics2D g) {
for (final Wire wire : circuit.getWires()) {
circuit.streamWires().forEach(wire -> {
final Point a = wire.getA().getAbsolute();
final Point b = wire.getB().getAbsolute();
g.setColor(wire.getA().getColor());
g.setStroke(WIRE_STROKE);
g.drawLine(a.x, a.y, b.x, b.y);
}
});
}
}

View File

@ -1,7 +1,7 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.parts.*;
import de.ph87.electro.common.AbstractDropTarget;
import java.awt.*;

View File

@ -45,10 +45,7 @@ class CircuitPanelMouseAdapter extends MouseAdapter {
if (e.getButton() == BUTTON3) {
final Optional<Wire> wireOptional = circuit.findWireByPoint(e.getPoint());
if (wireOptional.isPresent()) {
final Wire wire = wireOptional.get();
wire.getA().getDestinations().remove(wire.getB());
wire.getB().getDestinations().remove(wire.getA());
circuit.evaluateAndRender();
circuit.removeWire(wireOptional.get());
circuitPanel.repaint();
return;
}

View File

@ -2,6 +2,7 @@ package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Junction;
import lombok.Data;
import lombok.NonNull;
import java.awt.*;
@ -10,17 +11,17 @@ import static de.ph87.electro.CONFIG.WIRE_STROKE_BACK2;
@Data
public class Wire {
@NonNull
private final Junction a;
@NonNull
private final Junction b;
public Wire(final Junction a, final Junction b) {
public Wire(@NonNull final Junction a, @NonNull final Junction b) {
this.a = a;
this.b = b;
}
public boolean matches(final Junction x, final Junction y) {
return (a == x && b == y) || (a == y && b == x);
a.getWires().add(this);
b.getWires().add(this);
}
public boolean intersects(final Point p) {
@ -40,4 +41,13 @@ public class Wire {
return p.distance(closestX, closestY) <= WIRE_STROKE_BACK2.getLineWidth();
}
public Junction getOpposite(final Junction junction) {
if (a == junction) {
return b;
} else if (b == junction) {
return a;
}
throw new RuntimeException();
}
}

View File

@ -0,0 +1,22 @@
package de.ph87.electro.circuit;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
@Getter
@ToString
@NoArgsConstructor
public class WireDto {
private String a;
private String b;
public WireDto(@NonNull final Wire wire) {
this.a = wire.getA().getUuid();
this.b = wire.getB().getUuid();
}
}

View File

@ -1,6 +1,7 @@
package de.ph87.electro.circuit.part;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.Wire;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -17,8 +18,6 @@ import static de.ph87.electro.CONFIG.*;
@ToString(onlyExplicitlyIncluded = true)
public class Junction {
private final JunctionDto _dto;
@ToString.Include
private final String uuid;
@ -29,7 +28,7 @@ public class Junction {
private final Point position;
private final Set<Junction> destinations = new HashSet<>();
private final Set<Wire> wires = new HashSet<>();
@Setter
@ToString.Include
@ -40,7 +39,7 @@ public class Junction {
@ToString.Include
@SuppressWarnings("unused") // lombok toString
public List<String> destinations() {
return destinations.stream().map(Junction::getUuid).toList();
return wires.stream().map(wire -> wire.getOpposite(this)).map(Junction::getUuid).toList();
}
public Junction(final Part owner, final String name, final Point position) {
@ -48,7 +47,6 @@ public class Junction {
this.uuid = UUID.randomUUID().toString();
this.name = name;
this.position = position;
this._dto = null;
}
public Junction(final Part owner, final JunctionDto dto, final Point position) {
@ -56,15 +54,6 @@ public class Junction {
this.uuid = dto.getUuid();
this.name = dto.getName();
this.position = position;
this._dto = dto;
}
public void link(final List<Junction> junctions) {
for (final String otherUuid : _dto.getDestinations()) {
final Junction other = junctions.stream().filter(junction -> junction.getUuid().equals(otherUuid)).findFirst().orElseThrow();
destinations.add(other);
other.destinations.add(this);
}
}
public void reset() {
@ -86,8 +75,8 @@ public class Junction {
color = VOLTAGE_LOW_COLOR;
}
owner.propagate(this);
for (Junction junction : destinations) {
junction.propagate(newVoltage);
for (Wire wire : wires) {
wire.getOpposite(this).propagate(newVoltage);
}
return;
}

View File

@ -4,8 +4,6 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.List;
@Getter
@ToString
@NoArgsConstructor
@ -15,12 +13,9 @@ public class JunctionDto {
private String name;
private List<String> destinations;
public JunctionDto(final Junction junction) {
this.uuid = junction.getUuid();
this.name = junction.getName();
this.destinations = junction.getDestinations().stream().map(Junction::getUuid).toList();
}
}

View File

@ -1,7 +1,7 @@
package de.ph87.electro.circuit.part;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.parts.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -51,10 +51,6 @@ public abstract class Part {
this.orientation = dto.getOrientation();
}
public void link(final List<Junction> junctions) {
junctions.forEach(junction -> junction.link(junctions));
}
protected Junction newJunction(final Part owner, final String name, final int x, final int y) {
return addJunction(new Junction(owner, name, new Point(x, y)));
}
@ -201,4 +197,8 @@ public abstract class Part {
};
}
public Optional<Junction> findJunctionByUuid(final String junctionUuid) {
return junctions.stream().filter(junction -> junction.getUuid().equals(junctionUuid)).findFirst();
}
}

View File

@ -1,7 +1,7 @@
package de.ph87.electro.circuit.part;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.parts.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.Junction;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.Junction;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.Junction;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.ShortCircuit;
import de.ph87.electro.circuit.part.Junction;

View File

@ -1,4 +1,4 @@
package de.ph87.electro.circuit.part.impl;
package de.ph87.electro.circuit.part.parts;
import de.ph87.electro.circuit.part.JunctionDto;
import de.ph87.electro.circuit.part.PartDto;

View File

@ -2,7 +2,7 @@ package de.ph87.electro.demo;
import de.ph87.electro.circuit.Circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.parts.*;
import static de.ph87.electro.CONFIG.BULB_VOLTAGE_MIN;
import static de.ph87.electro.CONFIG.VOLTAGE;

View File

@ -1,7 +1,7 @@
package de.ph87.electro.sidebar;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.impl.*;
import de.ph87.electro.circuit.part.parts.*;
import javax.swing.*;
import java.awt.*;

View File

@ -1,8 +1,8 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -1,9 +1,9 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.impl.PartSwitch1x1;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import de.ph87.electro.circuit.part.parts.PartSwitch1x1;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -1,9 +1,9 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.impl.PartSwitch1x2;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import de.ph87.electro.circuit.part.parts.PartSwitch1x2;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -1,9 +1,9 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.impl.PartSwitch1x2;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import de.ph87.electro.circuit.part.parts.PartSwitch1x2;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -1,10 +1,10 @@
package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.impl.PartSwitch1x2;
import de.ph87.electro.circuit.part.impl.PartSwitchCross;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import de.ph87.electro.circuit.part.parts.PartSwitch1x2;
import de.ph87.electro.circuit.part.parts.PartSwitchCross;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -3,8 +3,8 @@ package de.ph87.electro.circuit;
import de.ph87.electro.circuit.part.Junction;
import de.ph87.electro.circuit.part.Orientation;
import de.ph87.electro.circuit.part.Part;
import de.ph87.electro.circuit.part.impl.PartBattery;
import de.ph87.electro.circuit.part.impl.PartLight;
import de.ph87.electro.circuit.part.parts.PartBattery;
import de.ph87.electro.circuit.part.parts.PartLight;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
@ -54,13 +54,16 @@ class CircuitServiceTest {
assertEquals(originalJunction.getUuid(), reloadedJunction.getUuid());
assertEquals(originalJunction.getName(), reloadedJunction.getName());
assertEquals(originalJunction.getPosition(), reloadedJunction.getPosition());
assertEquals(originalJunction.getDestinations().size(), reloadedJunction.getDestinations().size());
for (final Junction originalDestination : originalJunction.getDestinations()) {
System.out.printf(" - Destination: %s\n", originalDestination.getUuid());
final Junction reloadedDestination = reloadedJunction.getDestinations().stream().filter(destination -> destination.getUuid().equals(originalDestination.getUuid())).findFirst().orElseThrow();
assertEquals(originalDestination.getUuid(), reloadedDestination.getUuid());
assertEquals(originalDestination.getOwner().getUuid(), reloadedDestination.getOwner().getUuid());
}
assertEquals(originalJunction.getWires().size(), reloadedJunction.getWires().size());
originalJunction.getWires().stream()
.map(originalWire -> originalWire.getOpposite(originalJunction))
.forEach(originalDestination -> {
System.out.printf(" - Destinations: %s\n", originalDestination.getUuid());
final Junction reloadedDestination = reloadedJunction.getWires().stream().map(wire -> wire.getOpposite(reloadedJunction)).filter(destination -> destination.getUuid().equals(originalDestination.getUuid())).findFirst().orElseThrow();
assertEquals(originalDestination.getUuid(), reloadedDestination.getUuid());
assertEquals(originalDestination.getOwner().getUuid(), reloadedDestination.getOwner().getUuid());
}
);
}
});
}