Circuit.dirty
This commit is contained in:
parent
857d7252a6
commit
3ddb117696
@ -7,27 +7,42 @@ import de.ph87.electro.circuit.part.Position;
|
|||||||
import de.ph87.electro.circuit.part.junction.Junction;
|
import de.ph87.electro.circuit.part.junction.Junction;
|
||||||
import de.ph87.electro.circuit.wire.Wire;
|
import de.ph87.electro.circuit.wire.Wire;
|
||||||
import de.ph87.electro.circuit.wire.WireDto;
|
import de.ph87.electro.circuit.wire.WireDto;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@NoArgsConstructor
|
import static de.ph87.electro.circuit.CircuitIOService.write;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class Circuit {
|
public class Circuit {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final ZonedDateTime created;
|
||||||
|
|
||||||
private final List<Part> parts = new ArrayList<>();
|
private final List<Part> parts = new ArrayList<>();
|
||||||
|
|
||||||
private final List<Wire> wires = new ArrayList<>();
|
private final List<Wire> wires = new ArrayList<>();
|
||||||
|
|
||||||
|
private boolean dirty = false;
|
||||||
|
|
||||||
|
public Circuit() {
|
||||||
|
this.created = ZonedDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
public Circuit(final CircuitDto dto) {
|
public Circuit(final CircuitDto dto) {
|
||||||
|
created = dto.getCreated();
|
||||||
for (PartDto partDto : dto.getParts()) {
|
for (PartDto partDto : dto.getParts()) {
|
||||||
final Part part = Part.of(partDto);
|
final Part part = Part.of(partDto);
|
||||||
if (!isFree(part.getPosition())) {
|
verifyFree(part.getPosition());
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
parts.add(part);
|
parts.add(part);
|
||||||
}
|
}
|
||||||
for (final WireDto wire : dto.getWires()) {
|
for (final WireDto wire : dto.getWires()) {
|
||||||
@ -35,26 +50,32 @@ public class Circuit {
|
|||||||
final Junction b = findJunctionByUuid(wire.getB()).orElseThrow();
|
final Junction b = findJunctionByUuid(wire.getB()).orElseThrow();
|
||||||
wires.add(new Wire(a, b));
|
wires.add(new Wire(a, b));
|
||||||
}
|
}
|
||||||
|
evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(final Junction a, final Junction b) {
|
public void connect(final Junction a, final Junction b) {
|
||||||
wires.add(new Wire(a, b));
|
wires.add(new Wire(a, b));
|
||||||
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void evaluate() {
|
public void disconnect(final Wire wire) {
|
||||||
Calculation.calculate(this);
|
if (!wires.contains(wire)) {
|
||||||
parts.forEach(Part::render);
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
wires.remove(wire);
|
||||||
|
wire.getA().getWires().remove(wire);
|
||||||
|
wire.getB().getWires().remove(wire);
|
||||||
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Part> T addPart(final T part) {
|
public <T extends Part> T addPart(final T part) {
|
||||||
if (parts.contains(part)) {
|
if (parts.contains(part)) {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
if (!isFree(part.getPosition())) {
|
verifyFree(part.getPosition());
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
parts.add(part);
|
parts.add(part);
|
||||||
part.render();
|
part.render();
|
||||||
|
setDirty();
|
||||||
return part;
|
return part;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,13 +83,41 @@ public class Circuit {
|
|||||||
if (!parts.contains(part)) {
|
if (!parts.contains(part)) {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
if (isFree(position)) {
|
verifyFree(position);
|
||||||
part.setPosition(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) {
|
private void verifyFree(final Position position) {
|
||||||
return parts.stream().noneMatch(part -> part.getPosition().equals(position));
|
if (parts.stream().anyMatch(part -> part.getPosition().equals(position))) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<Part> streamParts() {
|
public Stream<Part> streamParts() {
|
||||||
@ -99,13 +148,4 @@ public class Circuit {
|
|||||||
return wires.stream().filter(wire -> wire.intersects(position)).findFirst();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ -13,11 +14,14 @@ import java.util.List;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class CircuitDto {
|
public class CircuitDto {
|
||||||
|
|
||||||
|
private ZonedDateTime created;
|
||||||
|
|
||||||
private List<PartDto> parts;
|
private List<PartDto> parts;
|
||||||
|
|
||||||
private List<WireDto> wires;
|
private List<WireDto> wires;
|
||||||
|
|
||||||
public CircuitDto(final Circuit circuit) {
|
public CircuitDto(final Circuit circuit) {
|
||||||
|
this.created = circuit.getCreated();
|
||||||
this.parts = circuit.streamParts().map(PartDto::of).toList();
|
this.parts = circuit.streamParts().map(PartDto::of).toList();
|
||||||
this.wires = circuit.streamWires().map(WireDto::new).toList();
|
this.wires = circuit.streamWires().map(WireDto::new).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
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.CONFIG.*;
|
||||||
import static de.ph87.electro.circuit.CircuitIOService.write;
|
|
||||||
import static de.ph87.electro.circuit.part.Position.RST;
|
import static de.ph87.electro.circuit.part.Position.RST;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -27,7 +23,6 @@ public class CircuitPanel extends JPanel {
|
|||||||
final PartLight light = circuit.addPart(new PartLight(RST(0, 1)));
|
final PartLight light = circuit.addPart(new PartLight(RST(0, 1)));
|
||||||
circuit.connect(battery.getMinus(), light.getA());
|
circuit.connect(battery.getMinus(), light.getA());
|
||||||
circuit.connect(light.getB(), battery.getPlus());
|
circuit.connect(light.getB(), battery.getPlus());
|
||||||
circuit.evaluate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -67,23 +62,4 @@ public class CircuitPanel extends JPanel {
|
|||||||
circuit.streamWires().forEach(wire -> wire.draw(g));
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package de.ph87.electro.circuit;
|
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.Position;
|
||||||
import de.ph87.electro.circuit.part.parts.*;
|
import de.ph87.electro.circuit.part.parts.*;
|
||||||
import de.ph87.electro.common.AbstractDropTarget;
|
import de.ph87.electro.common.AbstractDropTarget;
|
||||||
@ -24,21 +23,21 @@ public class CircuitPanelDropTarget extends AbstractDropTarget {
|
|||||||
protected boolean drop(final Point point, final String data) {
|
protected boolean drop(final Point point, final String data) {
|
||||||
final Position position = new Position(point);
|
final Position position = new Position(point);
|
||||||
if (data.equals(PartBattery.class.getSimpleName())) {
|
if (data.equals(PartBattery.class.getSimpleName())) {
|
||||||
addPart(new PartBattery(position));
|
circuit.addPart(new PartBattery(position));
|
||||||
} else if (data.equals(PartJunctionCorner.class.getSimpleName())) {
|
} else if (data.equals(PartJunctionCorner.class.getSimpleName())) {
|
||||||
addPart(new PartJunctionCorner(position));
|
circuit.addPart(new PartJunctionCorner(position));
|
||||||
} else if (data.equals(PartJunctionEdge.class.getSimpleName())) {
|
} else if (data.equals(PartJunctionEdge.class.getSimpleName())) {
|
||||||
addPart(new PartJunctionEdge(position));
|
circuit.addPart(new PartJunctionEdge(position));
|
||||||
} else if (data.equals(PartJunctionMiddle.class.getSimpleName())) {
|
} else if (data.equals(PartJunctionMiddle.class.getSimpleName())) {
|
||||||
addPart(new PartJunctionMiddle(position));
|
circuit.addPart(new PartJunctionMiddle(position));
|
||||||
} else if (data.equals(PartLight.class.getSimpleName())) {
|
} else if (data.equals(PartLight.class.getSimpleName())) {
|
||||||
addPart(new PartLight(position));
|
circuit.addPart(new PartLight(position));
|
||||||
} else if (data.equals(PartSwitch1x1.class.getSimpleName())) {
|
} else if (data.equals(PartSwitch1x1.class.getSimpleName())) {
|
||||||
addPart(new PartSwitch1x1(position));
|
circuit.addPart(new PartSwitch1x1(position));
|
||||||
} else if (data.equals(PartSwitch1x2.class.getSimpleName())) {
|
} else if (data.equals(PartSwitch1x2.class.getSimpleName())) {
|
||||||
addPart(new PartSwitch1x2(position));
|
circuit.addPart(new PartSwitch1x2(position));
|
||||||
} else if (data.equals(PartSwitchCross.class.getSimpleName())) {
|
} else if (data.equals(PartSwitchCross.class.getSimpleName())) {
|
||||||
addPart(new PartSwitchCross(position));
|
circuit.addPart(new PartSwitchCross(position));
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
@ -46,9 +45,4 @@ public class CircuitPanelDropTarget extends AbstractDropTarget {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPart(final Part part) {
|
|
||||||
circuit.addPart(part);
|
|
||||||
circuitPanel.evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,8 @@ class CircuitPanelMouseAdapter extends MouseAdapter {
|
|||||||
if (event.getButton() == BUTTON3) {
|
if (event.getButton() == BUTTON3) {
|
||||||
final Optional<Wire> wireOptional = circuit.findWireByPosition(position);
|
final Optional<Wire> wireOptional = circuit.findWireByPosition(position);
|
||||||
if (wireOptional.isPresent()) {
|
if (wireOptional.isPresent()) {
|
||||||
circuit.removeWire(wireOptional.get());
|
circuit.disconnect(wireOptional.get());
|
||||||
circuitPanel.evaluate();
|
circuitPanel.repaint();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,11 +56,11 @@ class CircuitPanelMouseAdapter extends MouseAdapter {
|
|||||||
switch (event.getButton()) {
|
switch (event.getButton()) {
|
||||||
case BUTTON1:
|
case BUTTON1:
|
||||||
partOptional.ifPresent(Part::action);
|
partOptional.ifPresent(Part::action);
|
||||||
circuitPanel.evaluate();
|
circuitPanel.repaint();
|
||||||
break;
|
break;
|
||||||
case BUTTON3:
|
case BUTTON3:
|
||||||
partOptional.ifPresent(Part::clockwise);
|
partOptional.ifPresent(Part::clockwise);
|
||||||
circuitPanel.save();
|
circuitPanel.repaint();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,14 +116,10 @@ class CircuitPanelMouseAdapter extends MouseAdapter {
|
|||||||
final Position position = new Position(event);
|
final Position position = new Position(event);
|
||||||
if (partDrag != null) {
|
if (partDrag != null) {
|
||||||
circuit.movePart(partDrag, position);
|
circuit.movePart(partDrag, position);
|
||||||
circuitPanel.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (junctionDrag != null) {
|
if (junctionDrag != null) {
|
||||||
circuit.findJunctionByAbsolute(position).filter(destination -> destination != junctionDrag).ifPresent(destination -> {
|
circuit.findJunctionByAbsolute(position).filter(destination -> destination != junctionDrag).ifPresent(destination -> circuit.connect(junctionDrag, destination));
|
||||||
circuit.connect(junctionDrag, destination);
|
|
||||||
circuitPanel.evaluate();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
partDrag = null;
|
partDrag = null;
|
||||||
@ -149,21 +145,11 @@ class CircuitPanelMouseAdapter extends MouseAdapter {
|
|||||||
if (wireHover != null) {
|
if (wireHover != null) {
|
||||||
g.setColor(WIRE_HOVER_COLOR_BACK);
|
g.setColor(WIRE_HOVER_COLOR_BACK);
|
||||||
g.setStroke(WIRE_HOVER_STROKE_BACK);
|
g.setStroke(WIRE_HOVER_STROKE_BACK);
|
||||||
g.drawLine(
|
g.drawLine(wireHover.getA().getPosition().absolute.x, wireHover.getA().getPosition().absolute.y, wireHover.getB().getPosition().absolute.x, wireHover.getB().getPosition().absolute.y);
|
||||||
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.setColor(wireHover.getA().getColor());
|
||||||
g.setStroke(WIRE_HOVER_STROKE);
|
g.setStroke(WIRE_HOVER_STROKE);
|
||||||
g.drawLine(
|
g.drawLine(wireHover.getA().getPosition().absolute.x, wireHover.getA().getPosition().absolute.y, wireHover.getB().getPosition().absolute.x, wireHover.getB().getPosition().absolute.y);
|
||||||
wireHover.getA().getPosition().absolute.x,
|
|
||||||
wireHover.getA().getPosition().absolute.y,
|
|
||||||
wireHover.getB().getPosition().absolute.x,
|
|
||||||
wireHover.getB().getPosition().absolute.y
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,9 +38,6 @@ class CircuitIOServiceTest {
|
|||||||
final ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
|
final ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
|
||||||
final Circuit reloaded = read(input);
|
final Circuit reloaded = read(input);
|
||||||
|
|
||||||
original.evaluate();
|
|
||||||
reloaded.evaluate();
|
|
||||||
|
|
||||||
assertEquals(original.getPartCount(), reloaded.getPartCount());
|
assertEquals(original.getPartCount(), reloaded.getPartCount());
|
||||||
original.streamParts().forEach(originalPart -> {
|
original.streamParts().forEach(originalPart -> {
|
||||||
System.out.printf("Part: %s\n", originalPart.getUuid());
|
System.out.printf("Part: %s\n", originalPart.getUuid());
|
||||||
|
|||||||
@ -26,8 +26,6 @@ public class BatteryLightTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void test() {
|
void test() {
|
||||||
CIRCUIT.evaluate();
|
|
||||||
|
|
||||||
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
||||||
assertVoltage(VOLTAGE, light.getB().getVoltage());
|
assertVoltage(VOLTAGE, light.getB().getVoltage());
|
||||||
assertVoltage(VOLTAGE, light.getPotentialDifference());
|
assertVoltage(VOLTAGE, light.getPotentialDifference());
|
||||||
|
|||||||
@ -43,8 +43,6 @@ public class BatterySwitcher1x1Test {
|
|||||||
|
|
||||||
switcher.setState(state);
|
switcher.setState(state);
|
||||||
|
|
||||||
CIRCUIT.evaluate();
|
|
||||||
|
|
||||||
assertEquals(state, switcher.isState());
|
assertEquals(state, switcher.isState());
|
||||||
|
|
||||||
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
||||||
|
|||||||
@ -48,8 +48,6 @@ public class BatterySwitcher1x2Test {
|
|||||||
|
|
||||||
switcher.setState(state);
|
switcher.setState(state);
|
||||||
|
|
||||||
CIRCUIT.evaluate();
|
|
||||||
|
|
||||||
assertEquals(state, switcher.isState());
|
assertEquals(state, switcher.isState());
|
||||||
|
|
||||||
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
assertVoltage(VOLTAGE, battery.getPlus().getVoltage());
|
||||||
|
|||||||
@ -60,8 +60,6 @@ public class BatterySwitcher2x2Test {
|
|||||||
switcher0.setState(state0);
|
switcher0.setState(state0);
|
||||||
switcher1.setState(state1);
|
switcher1.setState(state1);
|
||||||
|
|
||||||
CIRCUIT.evaluate();
|
|
||||||
|
|
||||||
assertEquals(state0, switcher0.isState());
|
assertEquals(state0, switcher0.isState());
|
||||||
assertEquals(state1, switcher1.isState());
|
assertEquals(state1, switcher1.isState());
|
||||||
|
|
||||||
|
|||||||
@ -87,8 +87,6 @@ public class BatterySwitcherCrossTest {
|
|||||||
switcherX.setState(stateX);
|
switcherX.setState(stateX);
|
||||||
switcher1.setState(state1);
|
switcher1.setState(state1);
|
||||||
|
|
||||||
CIRCUIT.evaluate();
|
|
||||||
|
|
||||||
assertEquals(state0, switcher0.isState());
|
assertEquals(state0, switcher0.isState());
|
||||||
assertEquals(stateX, switcherX.isState());
|
assertEquals(stateX, switcherX.isState());
|
||||||
assertEquals(state1, switcher1.isState());
|
assertEquals(state1, switcher1.isState());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user