152 lines
4.0 KiB
Java
152 lines
4.0 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.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.Getter;
|
|
import lombok.NonNull;
|
|
import lombok.Setter;
|
|
|
|
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;
|
|
|
|
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) {
|
|
created = dto.getCreated();
|
|
for (PartDto partDto : dto.getParts()) {
|
|
final Part part = Part.fromDto(this, partDto);
|
|
verifyFree(part.getPosition());
|
|
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));
|
|
}
|
|
evaluate();
|
|
}
|
|
|
|
public void connect(final Junction a, final Junction b) {
|
|
wires.add(new Wire(a, b));
|
|
evaluate();
|
|
}
|
|
|
|
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);
|
|
evaluate();
|
|
}
|
|
|
|
public <T extends Part> T addPart(final T part) {
|
|
if (parts.contains(part)) {
|
|
throw new RuntimeException();
|
|
}
|
|
verifyFree(part.getPosition());
|
|
parts.add(part);
|
|
part.render();
|
|
evaluate();
|
|
return part;
|
|
}
|
|
|
|
public void removePart(final Part part) {
|
|
if (parts.remove(part)) {
|
|
part.getJunctions().stream().flatMap(junction -> junction.getWires().stream()).toList().forEach(this::disconnect); // jep, first toList(), then forEach (due to concurrent modification)
|
|
} else {
|
|
throw new RuntimeException();
|
|
}
|
|
evaluate();
|
|
}
|
|
|
|
public void movePart(final Part part, final Position position) {
|
|
if (!parts.contains(part)) {
|
|
throw new RuntimeException();
|
|
}
|
|
verifyFree(position);
|
|
part.setPosition(position);
|
|
evaluate();
|
|
}
|
|
|
|
public void evaluate() {
|
|
Calculation.calculate(this);
|
|
parts.forEach(Part::render);
|
|
save();
|
|
}
|
|
|
|
public void save() {
|
|
CircuitIOService.save(this);
|
|
}
|
|
|
|
private void verifyFree(final Position position) {
|
|
if (parts.stream().anyMatch(part -> part.getPosition().equals(position))) {
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
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 Position position) {
|
|
return streamParts().filter(p -> p.getPosition().raster.equals(position.raster)).findFirst();
|
|
}
|
|
|
|
public Optional<Junction> findJunctionByAbsolute(final Position position) {
|
|
return findPartByPosition(position).flatMap(part -> part.findJunctionByPosition(position));
|
|
}
|
|
|
|
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> findWireByPosition(final Position 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"));
|
|
}
|
|
|
|
}
|