diff --git a/src/main/java/de/ph87/electro/circuit/Circuit.java b/src/main/java/de/ph87/electro/circuit/Circuit.java index 34642f7..c253164 100644 --- a/src/main/java/de/ph87/electro/circuit/Circuit.java +++ b/src/main/java/de/ph87/electro/circuit/Circuit.java @@ -7,27 +7,42 @@ import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.junction.Junction; import de.ph87.electro.circuit.wire.Wire; import de.ph87.electro.circuit.wire.WireDto; -import lombok.NoArgsConstructor; +import lombok.Getter; import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; -@NoArgsConstructor +import static de.ph87.electro.circuit.CircuitIOService.write; + +@Slf4j public class Circuit { + @Getter + private final ZonedDateTime created; + private final List parts = new ArrayList<>(); private final List wires = new ArrayList<>(); + private boolean dirty = false; + + public Circuit() { + this.created = ZonedDateTime.now(); + } + public Circuit(final CircuitDto dto) { + created = dto.getCreated(); for (PartDto partDto : dto.getParts()) { final Part part = Part.of(partDto); - if (!isFree(part.getPosition())) { - throw new RuntimeException(); - } + verifyFree(part.getPosition()); parts.add(part); } for (final WireDto wire : dto.getWires()) { @@ -35,26 +50,32 @@ public class Circuit { final Junction b = findJunctionByUuid(wire.getB()).orElseThrow(); wires.add(new Wire(a, b)); } + evaluate(); } public void connect(final Junction a, final Junction b) { wires.add(new Wire(a, b)); + setDirty(); } - public void evaluate() { - Calculation.calculate(this); - parts.forEach(Part::render); + public void disconnect(final Wire wire) { + if (!wires.contains(wire)) { + throw new RuntimeException(); + } + wires.remove(wire); + wire.getA().getWires().remove(wire); + wire.getB().getWires().remove(wire); + setDirty(); } public T addPart(final T part) { if (parts.contains(part)) { throw new RuntimeException(); } - if (!isFree(part.getPosition())) { - throw new RuntimeException(); - } + verifyFree(part.getPosition()); parts.add(part); part.render(); + setDirty(); return part; } @@ -62,13 +83,41 @@ public class Circuit { if (!parts.contains(part)) { throw new RuntimeException(); } - if (isFree(position)) { - part.setPosition(position); + verifyFree(position); + part.setPosition(position); + setDirty(); + } + + private void setDirty() { + evaluate(); + dirty = true; + } + + private void evaluate() { + Calculation.calculate(this); + parts.forEach(Part::render); + } + + public void save() { + if (!dirty) { + return; + } + try { + final File file = new File("./data/circuit.json"); + if (file.getParentFile().mkdirs()) { + log.info("Directory created: {}", file.getParent()); + } + write(this, new FileOutputStream(file)); + dirty = false; + } catch (IOException e) { + log.error(e.toString()); } } - public boolean isFree(final Position position) { - return parts.stream().noneMatch(part -> part.getPosition().equals(position)); + private void verifyFree(final Position position) { + if (parts.stream().anyMatch(part -> part.getPosition().equals(position))) { + throw new RuntimeException(); + } } public Stream streamParts() { @@ -99,13 +148,4 @@ public class Circuit { return wires.stream().filter(wire -> wire.intersects(position)).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); - } - } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitDto.java b/src/main/java/de/ph87/electro/circuit/CircuitDto.java index e1accd6..5f0abf0 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitDto.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitDto.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; +import java.time.ZonedDateTime; import java.util.List; @Getter @@ -13,11 +14,14 @@ import java.util.List; @NoArgsConstructor public class CircuitDto { + private ZonedDateTime created; + private List parts; private List wires; public CircuitDto(final Circuit circuit) { + this.created = circuit.getCreated(); this.parts = circuit.streamParts().map(PartDto::of).toList(); this.wires = circuit.streamWires().map(WireDto::new).toList(); } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java index 089c475..fa1fd17 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanel.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanel.java @@ -6,12 +6,8 @@ import lombok.extern.slf4j.Slf4j; import javax.swing.*; import java.awt.*; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import static de.ph87.electro.CONFIG.*; -import static de.ph87.electro.circuit.CircuitIOService.write; import static de.ph87.electro.circuit.part.Position.RST; @Slf4j @@ -27,7 +23,6 @@ public class CircuitPanel extends JPanel { final PartLight light = circuit.addPart(new PartLight(RST(0, 1))); circuit.connect(battery.getMinus(), light.getA()); circuit.connect(light.getB(), battery.getPlus()); - circuit.evaluate(); } @Override @@ -67,23 +62,4 @@ public class CircuitPanel extends JPanel { circuit.streamWires().forEach(wire -> wire.draw(g)); } - public void evaluate() { - circuit.evaluate(); - save(); - } - - public void save() { - // TODO make async - try { - final File file = new File("./data/circuit.json"); - if (file.getParentFile().mkdirs()) { - log.info("Directory created: {}", file.getParent()); - } - write(circuit, new FileOutputStream(file)); - } catch (IOException e) { - log.error(e.toString()); - } - repaint(); - } - } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanelDropTarget.java b/src/main/java/de/ph87/electro/circuit/CircuitPanelDropTarget.java index adf0346..f249b94 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanelDropTarget.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanelDropTarget.java @@ -1,6 +1,5 @@ package de.ph87.electro.circuit; -import de.ph87.electro.circuit.part.Part; import de.ph87.electro.circuit.part.Position; import de.ph87.electro.circuit.part.parts.*; import de.ph87.electro.common.AbstractDropTarget; @@ -24,21 +23,21 @@ public class CircuitPanelDropTarget extends AbstractDropTarget { protected boolean drop(final Point point, final String data) { final Position position = new Position(point); if (data.equals(PartBattery.class.getSimpleName())) { - addPart(new PartBattery(position)); + circuit.addPart(new PartBattery(position)); } else if (data.equals(PartJunctionCorner.class.getSimpleName())) { - addPart(new PartJunctionCorner(position)); + circuit.addPart(new PartJunctionCorner(position)); } else if (data.equals(PartJunctionEdge.class.getSimpleName())) { - addPart(new PartJunctionEdge(position)); + circuit.addPart(new PartJunctionEdge(position)); } else if (data.equals(PartJunctionMiddle.class.getSimpleName())) { - addPart(new PartJunctionMiddle(position)); + circuit.addPart(new PartJunctionMiddle(position)); } else if (data.equals(PartLight.class.getSimpleName())) { - addPart(new PartLight(position)); + circuit.addPart(new PartLight(position)); } else if (data.equals(PartSwitch1x1.class.getSimpleName())) { - addPart(new PartSwitch1x1(position)); + circuit.addPart(new PartSwitch1x1(position)); } else if (data.equals(PartSwitch1x2.class.getSimpleName())) { - addPart(new PartSwitch1x2(position)); + circuit.addPart(new PartSwitch1x2(position)); } else if (data.equals(PartSwitchCross.class.getSimpleName())) { - addPart(new PartSwitchCross(position)); + circuit.addPart(new PartSwitchCross(position)); } else { throw new RuntimeException(); } @@ -46,9 +45,4 @@ public class CircuitPanelDropTarget extends AbstractDropTarget { return true; } - public void addPart(final Part part) { - circuit.addPart(part); - circuitPanel.evaluate(); - } - } diff --git a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java index 00058c9..6b29c94 100644 --- a/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java +++ b/src/main/java/de/ph87/electro/circuit/CircuitPanelMouseAdapter.java @@ -46,8 +46,8 @@ class CircuitPanelMouseAdapter extends MouseAdapter { if (event.getButton() == BUTTON3) { final Optional wireOptional = circuit.findWireByPosition(position); if (wireOptional.isPresent()) { - circuit.removeWire(wireOptional.get()); - circuitPanel.evaluate(); + circuit.disconnect(wireOptional.get()); + circuitPanel.repaint(); return; } } @@ -56,11 +56,11 @@ class CircuitPanelMouseAdapter extends MouseAdapter { switch (event.getButton()) { case BUTTON1: partOptional.ifPresent(Part::action); - circuitPanel.evaluate(); + circuitPanel.repaint(); break; case BUTTON3: partOptional.ifPresent(Part::clockwise); - circuitPanel.save(); + circuitPanel.repaint(); break; } } @@ -116,14 +116,10 @@ class CircuitPanelMouseAdapter extends MouseAdapter { final Position position = new Position(event); if (partDrag != null) { circuit.movePart(partDrag, position); - circuitPanel.save(); } if (junctionDrag != null) { - circuit.findJunctionByAbsolute(position).filter(destination -> destination != junctionDrag).ifPresent(destination -> { - circuit.connect(junctionDrag, destination); - circuitPanel.evaluate(); - }); + circuit.findJunctionByAbsolute(position).filter(destination -> destination != junctionDrag).ifPresent(destination -> circuit.connect(junctionDrag, destination)); } partDrag = null; @@ -149,21 +145,11 @@ class CircuitPanelMouseAdapter extends MouseAdapter { if (wireHover != null) { g.setColor(WIRE_HOVER_COLOR_BACK); g.setStroke(WIRE_HOVER_STROKE_BACK); - g.drawLine( - wireHover.getA().getPosition().absolute.x, - wireHover.getA().getPosition().absolute.y, - wireHover.getB().getPosition().absolute.x, - wireHover.getB().getPosition().absolute.y - ); + g.drawLine(wireHover.getA().getPosition().absolute.x, wireHover.getA().getPosition().absolute.y, wireHover.getB().getPosition().absolute.x, wireHover.getB().getPosition().absolute.y); g.setColor(wireHover.getA().getColor()); g.setStroke(WIRE_HOVER_STROKE); - g.drawLine( - wireHover.getA().getPosition().absolute.x, - wireHover.getA().getPosition().absolute.y, - wireHover.getB().getPosition().absolute.x, - wireHover.getB().getPosition().absolute.y - ); + g.drawLine(wireHover.getA().getPosition().absolute.x, wireHover.getA().getPosition().absolute.y, wireHover.getB().getPosition().absolute.x, wireHover.getB().getPosition().absolute.y); } } diff --git a/src/test/java/de/ph87/electro/circuit/io/CircuitIOServiceTest.java b/src/test/java/de/ph87/electro/circuit/io/CircuitIOServiceTest.java index 09a7e3f..48d8e48 100644 --- a/src/test/java/de/ph87/electro/circuit/io/CircuitIOServiceTest.java +++ b/src/test/java/de/ph87/electro/circuit/io/CircuitIOServiceTest.java @@ -38,9 +38,6 @@ class CircuitIOServiceTest { final ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); final Circuit reloaded = read(input); - original.evaluate(); - reloaded.evaluate(); - assertEquals(original.getPartCount(), reloaded.getPartCount()); original.streamParts().forEach(originalPart -> { System.out.printf("Part: %s\n", originalPart.getUuid()); diff --git a/src/test/java/de/ph87/electro/circuit/part/parts/BatteryLightTest.java b/src/test/java/de/ph87/electro/circuit/part/parts/BatteryLightTest.java index af8118f..a41b317 100644 --- a/src/test/java/de/ph87/electro/circuit/part/parts/BatteryLightTest.java +++ b/src/test/java/de/ph87/electro/circuit/part/parts/BatteryLightTest.java @@ -26,8 +26,6 @@ public class BatteryLightTest { @Test void test() { - CIRCUIT.evaluate(); - assertVoltage(VOLTAGE, battery.getPlus().getVoltage()); assertVoltage(VOLTAGE, light.getB().getVoltage()); assertVoltage(VOLTAGE, light.getPotentialDifference()); diff --git a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x1Test.java b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x1Test.java index 0804d50..fc2d9b2 100644 --- a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x1Test.java +++ b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x1Test.java @@ -43,8 +43,6 @@ public class BatterySwitcher1x1Test { switcher.setState(state); - CIRCUIT.evaluate(); - assertEquals(state, switcher.isState()); assertVoltage(VOLTAGE, battery.getPlus().getVoltage()); diff --git a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x2Test.java b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x2Test.java index 728da0a..d569621 100644 --- a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x2Test.java +++ b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher1x2Test.java @@ -48,8 +48,6 @@ public class BatterySwitcher1x2Test { switcher.setState(state); - CIRCUIT.evaluate(); - assertEquals(state, switcher.isState()); assertVoltage(VOLTAGE, battery.getPlus().getVoltage()); diff --git a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher2x2Test.java b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher2x2Test.java index 0cfcbf1..eb60874 100644 --- a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher2x2Test.java +++ b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcher2x2Test.java @@ -60,8 +60,6 @@ public class BatterySwitcher2x2Test { switcher0.setState(state0); switcher1.setState(state1); - CIRCUIT.evaluate(); - assertEquals(state0, switcher0.isState()); assertEquals(state1, switcher1.isState()); diff --git a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcherCrossTest.java b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcherCrossTest.java index 8d36c13..223314c 100644 --- a/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcherCrossTest.java +++ b/src/test/java/de/ph87/electro/circuit/part/parts/BatterySwitcherCrossTest.java @@ -87,8 +87,6 @@ public class BatterySwitcherCrossTest { switcherX.setState(stateX); switcher1.setState(state1); - CIRCUIT.evaluate(); - assertEquals(state0, switcher0.isState()); assertEquals(stateX, switcherX.isState()); assertEquals(state1, switcher1.isState());