added load and save

MS-JK is working
This commit is contained in:
hneemann 2016-03-17 21:00:07 +01:00
parent 57bc84a832
commit 9200771046
15 changed files with 129 additions and 32 deletions

View File

@ -8,11 +8,12 @@ import java.util.Collections;
*/
public class Model {
private ArrayList<Node> nodes;
private final ArrayList<Node> nodes;
private ArrayList<Node> nodesToUpdateAct;
private ArrayList<Node> nodesToUpdateNext;
private int version;
private int maxCounter = 1000;
private Listener listener;
public Model() {
this.nodes = new ArrayList<>();
@ -66,6 +67,8 @@ public class Model {
if (counter++ > maxCounter) {
throw new NodeException("seemsToOscillate");
}
if (listener != null)
listener.needsUpdate();
}
}
@ -77,4 +80,8 @@ public class Model {
nodesToUpdateNext.addAll(nodes);
doStep(noise);
}
public void setListener(Listener listener) {
this.listener = listener;
}
}

View File

@ -45,6 +45,7 @@ public class ObservableValue extends Value {
}
public void setValue(long value) {
value = getValueBits(value);
if (this.value != value) {
this.value = value;
if (!highZ)
@ -52,12 +53,8 @@ public class ObservableValue extends Value {
}
}
public long getValueBits() {
return getValueBits(getValue());
}
public long getValueBits(long value) {
return value & (1 << bits) - 1;
return value & ((1 << bits) - 1);
}
public void checkBits(ObservableValue value) throws BitsException {

View File

@ -36,7 +36,7 @@ public class Add extends Node implements Part {
@Override
public void readInputs() throws NodeException {
value = a.getValueBits() + b.getValueBits() + c_in.getValueBits();
value = a.getValue() + b.getValue() + c_in.getValue();
}
@Override

View File

@ -28,7 +28,7 @@ public class Mul extends Node implements Part {
@Override
public void readInputs() throws NodeException {
value = a.getValueBits() * b.getValueBits();
value = a.getValue() * b.getValue();
}
@Override

View File

@ -26,6 +26,6 @@ public class Sub extends Add {
@Override
public void readInputs() throws NodeException {
value = a.getValueBits() - b.getValueBits() - c_in.getValueBits();
value = a.getValue() - b.getValue() - c_in.getValue();
}
}

View File

@ -23,7 +23,7 @@ public class Multiplexer extends FanIn {
@Override
public void readInputs() throws NodeException {
int n = (int) selector.getValueBits();
int n = (int) selector.getValue();
if (n >= inputs.size())
throw new NodeException("multiplexerSelectsNotPresentInput");

View File

@ -19,16 +19,20 @@ import de.process.utils.gui.ErrorMessage;
import de.process.utils.gui.ToolTipAction;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.prefs.Preferences;
/**
* @author hneemann
*/
public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
private static final Preferences prefs = Preferences.userRoot().node("dig");
private final CircuitComponent circuitComponent;
private final InsertHistory insertHistory;
private final ToolTipAction save;
@ -40,6 +44,11 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
Circuit cr = new Circuit();
circuitComponent = new CircuitComponent(cr);
String name = prefs.get("name", null);
if (name != null) {
loadFile(new File(name));
}
getContentPane().add(circuitComponent);
addWindowListener(new ClosingWindowListener(this, this));
@ -54,14 +63,17 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
ToolTipAction open = new ToolTipAction("Open") {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = getjFileChooser();
if (fc.showOpenDialog(Main.this) == JFileChooser.APPROVE_OPTION) {
loadFile(fc.getSelectedFile());
}
}
};
ToolTipAction saveas = new ToolTipAction("Save As") {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser(filename == null ? null : filename.getParentFile());
JFileChooser fc = getjFileChooser();
if (fc.showSaveDialog(Main.this) == JFileChooser.APPROVE_OPTION) {
saveFile(fc.getSelectedFile());
}
@ -113,7 +125,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
@Override
public void actionPerformed(ActionEvent e) {
try {
ModelDescription m = new ModelDescription(cr);
ModelDescription m = new ModelDescription(circuitComponent.getCircuit());
Model model = m.create(circuitComponent);
model.init(true);
circuitComponent.setMode(CircuitComponent.Mode.running);
@ -143,6 +155,20 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
SwingUtilities.invokeLater(() -> new Main().setVisible(true));
}
private static XStream getxStream() {
XStream xStream = new XStream(new StaxDriver());
xStream.alias("visualPart", VisualPart.class);
xStream.alias("wire", Wire.class);
xStream.alias("circuit", Circuit.class);
return xStream;
}
private JFileChooser getjFileChooser() {
JFileChooser fileChooser = new JFileChooser(filename == null ? null : filename.getParentFile());
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Circuit", "dig"));
return fileChooser;
}
@Override
public boolean isStateChanged() {
return false;
@ -153,14 +179,30 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
save.actionPerformed(null);
}
private void saveFile(File filename) {
XStream xStream = new XStream(new StaxDriver());
xStream.alias("visualPart", VisualPart.class);
xStream.alias("wire", Wire.class);
xStream.alias("circuit", Circuit.class);
private void loadFile(File filename) {
XStream xStream = getxStream();
try (FileReader in = new FileReader(filename)) {
circuitComponent.setCircuit((Circuit) xStream.fromXML(in));
setFilename(filename);
} catch (IOException e) {
new ErrorMessage("error writing a file").addCause(e).show();
}
}
private void setFilename(File filename) {
this.filename = filename;
prefs.put("name", filename.getPath());
setTitle(filename + " - Digital");
}
private void saveFile(File filename) {
if (!filename.getName().endsWith(".dig"))
filename = new File(filename.getPath() + ".dig");
XStream xStream = getxStream();
try (FileWriter out = new FileWriter(filename)) {
xStream.marshal(circuitComponent.getCircuit(), new PrettyPrintWriter(out));
setFilename(filename);
} catch (IOException e) {
new ErrorMessage("error writing a file").addCause(e).show();
}

View File

@ -23,11 +23,11 @@ import java.util.ArrayList;
public class CircuitComponent extends JComponent implements Listener {
private static final String delAction = "myDelAction";
private final Circuit circuit;
private Circuit circuit;
private Mouse listener;
public CircuitComponent(Circuit circuit) {
this.circuit = circuit;
public CircuitComponent(Circuit aCircuit) {
this.circuit = aCircuit;
setMode(Mode.part);
KeyStroke delKey = KeyStroke.getKeyStroke("DELETE");
@ -35,7 +35,6 @@ public class CircuitComponent extends JComponent implements Listener {
getActionMap().put(delAction, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("write");
if (listener instanceof SelectMouseListener) {
SelectMouseListener mml = (SelectMouseListener) listener;
if (mml.corner1 != null && mml.corner2 != null) {
@ -110,6 +109,11 @@ public class CircuitComponent extends JComponent implements Listener {
return circuit;
}
public void setCircuit(Circuit circuit) {
this.circuit = circuit;
setMode(Mode.part);
}
public enum Mode {part, wire, running, select}
private interface Mouse extends MouseMotionListener, MouseListener {

View File

@ -7,8 +7,8 @@ import java.awt.*;
*/
public class Style {
public static final Style NORMAL = new Style(2, false, Color.BLACK);
public static final Style WIRE = new Style(2, true, Color.BLUE);
public static final Style WIRE_HIGH = new Style(2, true, new Color(0, 153, 255));
public static final Style WIRE = new Style(3, true, new Color(0, 112, 0));
public static final Style WIRE_HIGH = new Style(3, true, new Color(102, 255, 102));
public static final Style FILLED = new Style(2, true, Color.BLACK);
public static final Style THIN = new Style(1, false, Color.BLACK);

View File

@ -16,20 +16,25 @@ public class Net {
private final HashSet<Vector> points;
private final ArrayList<Pin> pins;
private final ArrayList<Wire> wires;
public Net(Wire w) {
points = new HashSet<>();
points.add(w.p1);
points.add(w.p2);
pins = new ArrayList<>();
wires = new ArrayList<>();
wires.add(w);
}
public Vector tryMerge(Wire wire) {
if (points.contains(wire.p1)) {
wires.add(wire);
points.add(wire.p2);
return wire.p2;
}
if (points.contains(wire.p2)) {
wires.add(wire);
points.add(wire.p1);
return wire.p1;
}
@ -42,6 +47,7 @@ public class Net {
public void addAllPointsFrom(Net changedNet) {
points.addAll(changedNet.points);
wires.addAll(changedNet.wires);
}
public void add(Pin pin) {
@ -71,5 +77,9 @@ public class Net {
for (Pin i : inputs) {
i.setValue(value);
}
for (Wire w : wires)
w.setValue(value);
}
}

View File

@ -12,7 +12,7 @@ import java.util.Iterator;
* @author hneemann
*/
public class Circuit implements Drawable {
private static final Vector RAD = new Vector(2, 2);
private static final Vector RAD = new Vector(3, 3);
private final ArrayList<VisualPart> visualParts;
private transient ArrayList<Vector> dots;
private ArrayList<Wire> wires;
@ -25,10 +25,10 @@ public class Circuit implements Drawable {
@Override
public void drawTo(Graphic graphic, State state) {
for (Vector d : getDots())
graphic.drawCircle(d.sub(RAD), d.add(RAD), Style.WIRE);
for (Wire w : wires)
w.drawTo(graphic, state);
for (Vector d : dots)
graphic.drawCircle(d.sub(RAD), d.add(RAD), Style.WIRE);
for (VisualPart p : visualParts)
p.drawTo(graphic, state);
}
@ -56,7 +56,7 @@ public class Circuit implements Drawable {
wires.add(newWire);
WireConsistencyChecker checker = new WireConsistencyChecker(wires);
wires = checker.check();
dots = WireConsistencyChecker.createDots(wires);
dots = null;
}
public ArrayList<VisualPart> getParts() {
@ -99,4 +99,10 @@ public class Circuit implements Drawable {
public ArrayList<Wire> getWires() {
return wires;
}
public ArrayList<Vector> getDots() {
if (dots == null)
dots = WireConsistencyChecker.createDots(wires);
return dots;
}
}

View File

@ -1,5 +1,6 @@
package de.neemann.digital.gui.draw.parts;
import de.neemann.digital.core.ObservableValue;
import de.neemann.digital.gui.draw.graphics.Graphic;
import de.neemann.digital.gui.draw.graphics.Style;
import de.neemann.digital.gui.draw.graphics.Vector;
@ -12,6 +13,7 @@ public class Wire implements Drawable, Moveable {
public Vector p1;
public Vector p2;
private ObservableValue value;
public Wire(Vector p1, Vector p2) {
this.p1 = p1;
@ -20,7 +22,12 @@ public class Wire implements Drawable, Moveable {
@Override
public void drawTo(Graphic graphic, State state) {
graphic.drawLine(p1, p2, Style.WIRE);
Style style = Style.WIRE;
if (value != null && value.getValue() != 0) {
style = Style.WIRE_HIGH;
}
graphic.drawLine(p1, p2, style);
}
@Override
@ -77,5 +84,9 @@ public class Wire implements Drawable, Moveable {
'}';
}
public void setValue(ObservableValue value) {
this.value = value;
}
enum Orientation {horzontal, vertical, diagonal}
}

View File

@ -76,6 +76,21 @@ public class GenericShape implements Shape {
@Override
public Interactor applyStateMonitor(State state, Listener listener, Model model) {
if (symmetric) {
state.getOutput(0).addListener(new Listener() {
public long lastValue = 0;
@Override
public void needsUpdate() {
long value = state.getInput(0).getValue();
if (lastValue != value) {
lastValue = value;
listener.needsUpdate();
}
}
});
}
return null;
}
@ -84,6 +99,11 @@ public class GenericShape implements Shape {
int max = Math.max(inputs, outputs);
int height = (max - 1) * SIZE + SIZE2;
if (symmetric && state != null) {
graphic.drawText(new Vector(width * SIZE, 0), new Vector((width + 1) * SIZE, 0), Long.toString(state.getOutput(0).getValue()));
}
if (symmetric && ((inputs & 1) == 0)) height += SIZE;
graphic.drawPolygon(new Polygon(true)

View File

@ -32,8 +32,8 @@ public class FlipFlops extends TestCase {
s.setValue(0);
model.doStep(true); // geht nur mit noise!
assertTrue((a1.getOutput().getValueBits() == 1 && a2.getOutput().getValueBits() == 0) || // endzustand ist undefiniert!
(a1.getOutput().getValueBits() == 0 && a2.getOutput().getValueBits() == 1));
assertTrue((a1.getOutput().getValue() == 1 && a2.getOutput().getValue() == 0) || // endzustand ist undefiniert!
(a1.getOutput().getValue() == 0 && a2.getOutput().getValue() == 1));
}
public void testFlipFlopNAnd() throws Exception {

View File

@ -43,7 +43,7 @@ public class TestExecuter {
for (int i = 0; i < outputs.length; i++) {
int should = val[i + inputs.length];
if (should >= 0)
assertEquals("output " + i, outputs[i].getValueBits(should), outputs[i].getValueBits());
assertEquals("output " + i, outputs[i].getValueBits(should), outputs[i].getValue());
}
}