bastools/api/src/main/java/io/github/applecommander/bastools/api/shapes/ExternalShapeImporter.java

99 lines
3.5 KiB
Java

package io.github.applecommander.bastools.api.shapes;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.IntStream;
import io.github.applecommander.bastools.api.utils.Converters;
/**
* Allow the import of an external shape. Processing is very dependent on
* being invoked in the "correct" manner!
* <p>
* Prototype code:
* <pre>
* ; Read in external shape table: configure first and then "import" processes file.
* .external characters
* type=bin
* shapes=1-96
* import=imperator.bin
* </pre>
*/
public class ExternalShapeImporter {
private ShapeTable destination;
private String firstShapeLabel;
private Function<String,ShapeTable> importer = this::importShapeTableFromBinary;
private IntStream intStream = null;
public ExternalShapeImporter(ShapeTable destination, String firstShapeLabel) {
this.destination = destination;
this.firstShapeLabel = firstShapeLabel;
}
public void process(String line) {
Objects.requireNonNull(line);
String[] parts = line.split("=");
if (parts.length != 2) {
throw new RuntimeException(String.format(".external fields require an assignment for '%s'", line));
}
switch (parts[0].toLowerCase()) {
case "type":
switch (parts[1].toLowerCase()) {
case "bin":
importer = this::importShapeTableFromBinary;
break;
case "src":
importer = this::importShapeTableFromSource;
break;
default:
throw new RuntimeException(String.format("Unknown import type specified: '%s'", line));
}
break;
case "shapes":
intStream = Converters.toIntStream(parts[1]);
break;
case "import":
ShapeTable temp = importer.apply(parts[1]);
// Shapes in Applesoft are 1 based but Java List object is 0 based...
intStream.map(n -> n-1).mapToObj(temp.shapes::get).forEach(this::importShape);
break;
default:
throw new RuntimeException(String.format("Unknown assignment '%s' for .external", line));
}
}
public ShapeTable importShapeTableFromBinary(String filename) {
// FIXME May need access to Configuration for these nested files?
try {
Objects.requireNonNull(intStream, ".external requires that 'shapes' is specified");
return ShapeTable.read(Paths.get(filename));
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
public ShapeTable importShapeTableFromSource(String filename) {
// FIXME May need access to Configuration for these nested files?
try {
Objects.requireNonNull(intStream, ".external requires that 'shapes' is specified");
return ShapeGenerator.generate(Paths.get(filename));
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
public void importShape(Shape shape) {
if (firstShapeLabel != null) {
VectorShape vshape = new VectorShape(firstShapeLabel);
vshape.vectors.addAll(shape.toVector().vectors);
destination.shapes.add(vshape);
firstShapeLabel = null;
} else {
destination.shapes.add(shape);
}
}
}