137 lines
3.6 KiB
Java
137 lines
3.6 KiB
Java
package de.ph87.electro.circuit;
|
|
|
|
import de.ph87.electro.circuit.calculation.Calculation;
|
|
import de.ph87.electro.circuit.part.Part;
|
|
import de.ph87.electro.circuit.part.PartDto;
|
|
import de.ph87.electro.circuit.part.node.Node;
|
|
import de.ph87.electro.circuit.wire.Wire;
|
|
import de.ph87.electro.circuit.wire.WireDto;
|
|
import lombok.Getter;
|
|
import lombok.NonNull;
|
|
import lombok.Setter;
|
|
|
|
import java.awt.*;
|
|
import java.io.File;
|
|
import java.time.ZonedDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.stream.Stream;
|
|
|
|
import static de.ph87.electro.CONFIG.ALIGN;
|
|
|
|
public class Circuit {
|
|
|
|
@Getter
|
|
private final String created;
|
|
|
|
@Getter
|
|
private final List<Part> parts = new ArrayList<>();
|
|
|
|
private final List<Wire> wires = new ArrayList<>();
|
|
|
|
@Setter
|
|
@Getter
|
|
private File file = null;
|
|
|
|
public Circuit() {
|
|
this.created = ZonedDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
|
}
|
|
|
|
@SuppressWarnings("unused")
|
|
public Circuit(final File file, final CircuitDto dto) {
|
|
this.created = dto.getCreated();
|
|
for (PartDto partDto : dto.getParts()) {
|
|
final Part part = Part.fromDto(partDto);
|
|
verifyFree(part.getPosition());
|
|
parts.add(part);
|
|
}
|
|
for (final WireDto wire : dto.getWires()) {
|
|
final Node a = findNodeByUuid(wire.getA()).orElseThrow();
|
|
final Node b = findNodeByUuid(wire.getB()).orElseThrow();
|
|
wires.add(new Wire(a, b));
|
|
}
|
|
}
|
|
|
|
public Wire connect(final Node a, final Node b) {
|
|
final Wire wire = new Wire(a, b);
|
|
wires.add(wire);
|
|
return wire;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public <T extends Part> T addPart(final T part) {
|
|
if (parts.contains(part)) {
|
|
throw new RuntimeException();
|
|
}
|
|
verifyFree(part.getPosition());
|
|
parts.add(part);
|
|
return part;
|
|
}
|
|
|
|
public void removePart(final Part part) {
|
|
if (parts.remove(part)) {
|
|
part.getNodes().stream().flatMap(node -> node.getWires().stream()).toList().forEach(this::disconnect); // jep, first toList(), then forEach (due to concurrent modification)
|
|
} else {
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
public void verifyFree(final Point position) {
|
|
if (isOccupied(position)) {
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
public boolean isOccupied(final Point position) {
|
|
final Point aligned = ALIGN(position);
|
|
return parts.stream().anyMatch(part -> part.getPosition().equals(aligned));
|
|
}
|
|
|
|
public Stream<Part> streamParts() {
|
|
return parts.stream();
|
|
}
|
|
|
|
public Stream<Wire> streamWires() {
|
|
return wires.stream();
|
|
}
|
|
|
|
public int getPartCount() {
|
|
return parts.size();
|
|
}
|
|
|
|
public Optional<Part> findPartByPosition(final Point position) {
|
|
final Point aligned = ALIGN(position);
|
|
return streamParts().filter(p -> p.getPosition().equals(aligned)).findFirst();
|
|
}
|
|
|
|
public Optional<Node> findNodeByUuid(@NonNull final String nodeUuid) {
|
|
return parts.stream().map(part -> part.findNodeByUuid(nodeUuid)).filter(Optional::isPresent).map(Optional::get).findFirst();
|
|
}
|
|
|
|
public Optional<Wire> findWireByPosition(final Point position) {
|
|
return wires.stream().filter(wire -> wire.intersects(position)).findFirst();
|
|
}
|
|
|
|
public File getPreviewFile() {
|
|
if (file == null) {
|
|
return null;
|
|
}
|
|
return new File(file.getAbsolutePath().replaceAll("\\.json$", ".png"));
|
|
}
|
|
|
|
public void evaluate() {
|
|
Calculation.calculate(this);
|
|
}
|
|
|
|
}
|