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 { public class Model {
private ArrayList<Node> nodes; private final ArrayList<Node> nodes;
private ArrayList<Node> nodesToUpdateAct; private ArrayList<Node> nodesToUpdateAct;
private ArrayList<Node> nodesToUpdateNext; private ArrayList<Node> nodesToUpdateNext;
private int version; private int version;
private int maxCounter = 1000; private int maxCounter = 1000;
private Listener listener;
public Model() { public Model() {
this.nodes = new ArrayList<>(); this.nodes = new ArrayList<>();
@ -66,6 +67,8 @@ public class Model {
if (counter++ > maxCounter) { if (counter++ > maxCounter) {
throw new NodeException("seemsToOscillate"); throw new NodeException("seemsToOscillate");
} }
if (listener != null)
listener.needsUpdate();
} }
} }
@ -77,4 +80,8 @@ public class Model {
nodesToUpdateNext.addAll(nodes); nodesToUpdateNext.addAll(nodes);
doStep(noise); 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) { public void setValue(long value) {
value = getValueBits(value);
if (this.value != value) { if (this.value != value) {
this.value = value; this.value = value;
if (!highZ) if (!highZ)
@ -52,12 +53,8 @@ public class ObservableValue extends Value {
} }
} }
public long getValueBits() {
return getValueBits(getValue());
}
public long getValueBits(long value) { public long getValueBits(long value) {
return value & (1 << bits) - 1; return value & ((1 << bits) - 1);
} }
public void checkBits(ObservableValue value) throws BitsException { public void checkBits(ObservableValue value) throws BitsException {

View File

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

View File

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

View File

@ -26,6 +26,6 @@ public class Sub extends Add {
@Override @Override
public void readInputs() throws NodeException { 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 @Override
public void readInputs() throws NodeException { public void readInputs() throws NodeException {
int n = (int) selector.getValueBits(); int n = (int) selector.getValue();
if (n >= inputs.size()) if (n >= inputs.size())
throw new NodeException("multiplexerSelectsNotPresentInput"); throw new NodeException("multiplexerSelectsNotPresentInput");

View File

@ -19,16 +19,20 @@ import de.process.utils.gui.ErrorMessage;
import de.process.utils.gui.ToolTipAction; import de.process.utils.gui.ToolTipAction;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.prefs.Preferences;
/** /**
* @author hneemann * @author hneemann
*/ */
public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
private static final Preferences prefs = Preferences.userRoot().node("dig");
private final CircuitComponent circuitComponent; private final CircuitComponent circuitComponent;
private final InsertHistory insertHistory; private final InsertHistory insertHistory;
private final ToolTipAction save; private final ToolTipAction save;
@ -40,6 +44,11 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
Circuit cr = new Circuit(); Circuit cr = new Circuit();
circuitComponent = new CircuitComponent(cr); circuitComponent = new CircuitComponent(cr);
String name = prefs.get("name", null);
if (name != null) {
loadFile(new File(name));
}
getContentPane().add(circuitComponent); getContentPane().add(circuitComponent);
addWindowListener(new ClosingWindowListener(this, this)); addWindowListener(new ClosingWindowListener(this, this));
@ -54,14 +63,17 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
ToolTipAction open = new ToolTipAction("Open") { ToolTipAction open = new ToolTipAction("Open") {
@Override @Override
public void actionPerformed(ActionEvent e) { 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") { ToolTipAction saveas = new ToolTipAction("Save As") {
@Override @Override
public void actionPerformed(ActionEvent e) { 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) { if (fc.showSaveDialog(Main.this) == JFileChooser.APPROVE_OPTION) {
saveFile(fc.getSelectedFile()); saveFile(fc.getSelectedFile());
} }
@ -113,7 +125,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
ModelDescription m = new ModelDescription(cr); ModelDescription m = new ModelDescription(circuitComponent.getCircuit());
Model model = m.create(circuitComponent); Model model = m.create(circuitComponent);
model.init(true); model.init(true);
circuitComponent.setMode(CircuitComponent.Mode.running); circuitComponent.setMode(CircuitComponent.Mode.running);
@ -143,6 +155,20 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
SwingUtilities.invokeLater(() -> new Main().setVisible(true)); 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 @Override
public boolean isStateChanged() { public boolean isStateChanged() {
return false; return false;
@ -153,14 +179,30 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
save.actionPerformed(null); save.actionPerformed(null);
} }
private void saveFile(File filename) { private void loadFile(File filename) {
XStream xStream = new XStream(new StaxDriver()); XStream xStream = getxStream();
xStream.alias("visualPart", VisualPart.class); try (FileReader in = new FileReader(filename)) {
xStream.alias("wire", Wire.class); circuitComponent.setCircuit((Circuit) xStream.fromXML(in));
xStream.alias("circuit", Circuit.class); 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)) { try (FileWriter out = new FileWriter(filename)) {
xStream.marshal(circuitComponent.getCircuit(), new PrettyPrintWriter(out)); xStream.marshal(circuitComponent.getCircuit(), new PrettyPrintWriter(out));
setFilename(filename);
} catch (IOException e) { } catch (IOException e) {
new ErrorMessage("error writing a file").addCause(e).show(); 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 { public class CircuitComponent extends JComponent implements Listener {
private static final String delAction = "myDelAction"; private static final String delAction = "myDelAction";
private final Circuit circuit; private Circuit circuit;
private Mouse listener; private Mouse listener;
public CircuitComponent(Circuit circuit) { public CircuitComponent(Circuit aCircuit) {
this.circuit = circuit; this.circuit = aCircuit;
setMode(Mode.part); setMode(Mode.part);
KeyStroke delKey = KeyStroke.getKeyStroke("DELETE"); KeyStroke delKey = KeyStroke.getKeyStroke("DELETE");
@ -35,7 +35,6 @@ public class CircuitComponent extends JComponent implements Listener {
getActionMap().put(delAction, new AbstractAction() { getActionMap().put(delAction, new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
System.out.println("write");
if (listener instanceof SelectMouseListener) { if (listener instanceof SelectMouseListener) {
SelectMouseListener mml = (SelectMouseListener) listener; SelectMouseListener mml = (SelectMouseListener) listener;
if (mml.corner1 != null && mml.corner2 != null) { if (mml.corner1 != null && mml.corner2 != null) {
@ -110,6 +109,11 @@ public class CircuitComponent extends JComponent implements Listener {
return circuit; return circuit;
} }
public void setCircuit(Circuit circuit) {
this.circuit = circuit;
setMode(Mode.part);
}
public enum Mode {part, wire, running, select} public enum Mode {part, wire, running, select}
private interface Mouse extends MouseMotionListener, MouseListener { private interface Mouse extends MouseMotionListener, MouseListener {

View File

@ -7,8 +7,8 @@ import java.awt.*;
*/ */
public class Style { public class Style {
public static final Style NORMAL = new Style(2, false, Color.BLACK); 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 = new Style(3, true, new Color(0, 112, 0));
public static final Style WIRE_HIGH = new Style(2, true, new Color(0, 153, 255)); 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 FILLED = new Style(2, true, Color.BLACK);
public static final Style THIN = new Style(1, false, 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 HashSet<Vector> points;
private final ArrayList<Pin> pins; private final ArrayList<Pin> pins;
private final ArrayList<Wire> wires;
public Net(Wire w) { public Net(Wire w) {
points = new HashSet<>(); points = new HashSet<>();
points.add(w.p1); points.add(w.p1);
points.add(w.p2); points.add(w.p2);
pins = new ArrayList<>(); pins = new ArrayList<>();
wires = new ArrayList<>();
wires.add(w);
} }
public Vector tryMerge(Wire wire) { public Vector tryMerge(Wire wire) {
if (points.contains(wire.p1)) { if (points.contains(wire.p1)) {
wires.add(wire);
points.add(wire.p2); points.add(wire.p2);
return wire.p2; return wire.p2;
} }
if (points.contains(wire.p2)) { if (points.contains(wire.p2)) {
wires.add(wire);
points.add(wire.p1); points.add(wire.p1);
return wire.p1; return wire.p1;
} }
@ -42,6 +47,7 @@ public class Net {
public void addAllPointsFrom(Net changedNet) { public void addAllPointsFrom(Net changedNet) {
points.addAll(changedNet.points); points.addAll(changedNet.points);
wires.addAll(changedNet.wires);
} }
public void add(Pin pin) { public void add(Pin pin) {
@ -71,5 +77,9 @@ public class Net {
for (Pin i : inputs) { for (Pin i : inputs) {
i.setValue(value); i.setValue(value);
} }
for (Wire w : wires)
w.setValue(value);
} }
} }

View File

@ -12,7 +12,7 @@ import java.util.Iterator;
* @author hneemann * @author hneemann
*/ */
public class Circuit implements Drawable { 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 final ArrayList<VisualPart> visualParts;
private transient ArrayList<Vector> dots; private transient ArrayList<Vector> dots;
private ArrayList<Wire> wires; private ArrayList<Wire> wires;
@ -25,10 +25,10 @@ public class Circuit implements Drawable {
@Override @Override
public void drawTo(Graphic graphic, State state) { 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) for (Wire w : wires)
w.drawTo(graphic, state); w.drawTo(graphic, state);
for (Vector d : dots)
graphic.drawCircle(d.sub(RAD), d.add(RAD), Style.WIRE);
for (VisualPart p : visualParts) for (VisualPart p : visualParts)
p.drawTo(graphic, state); p.drawTo(graphic, state);
} }
@ -56,7 +56,7 @@ public class Circuit implements Drawable {
wires.add(newWire); wires.add(newWire);
WireConsistencyChecker checker = new WireConsistencyChecker(wires); WireConsistencyChecker checker = new WireConsistencyChecker(wires);
wires = checker.check(); wires = checker.check();
dots = WireConsistencyChecker.createDots(wires); dots = null;
} }
public ArrayList<VisualPart> getParts() { public ArrayList<VisualPart> getParts() {
@ -99,4 +99,10 @@ public class Circuit implements Drawable {
public ArrayList<Wire> getWires() { public ArrayList<Wire> getWires() {
return wires; 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; 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.Graphic;
import de.neemann.digital.gui.draw.graphics.Style; import de.neemann.digital.gui.draw.graphics.Style;
import de.neemann.digital.gui.draw.graphics.Vector; import de.neemann.digital.gui.draw.graphics.Vector;
@ -12,6 +13,7 @@ public class Wire implements Drawable, Moveable {
public Vector p1; public Vector p1;
public Vector p2; public Vector p2;
private ObservableValue value;
public Wire(Vector p1, Vector p2) { public Wire(Vector p1, Vector p2) {
this.p1 = p1; this.p1 = p1;
@ -20,7 +22,12 @@ public class Wire implements Drawable, Moveable {
@Override @Override
public void drawTo(Graphic graphic, State state) { 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 @Override
@ -77,5 +84,9 @@ public class Wire implements Drawable, Moveable {
'}'; '}';
} }
public void setValue(ObservableValue value) {
this.value = value;
}
enum Orientation {horzontal, vertical, diagonal} enum Orientation {horzontal, vertical, diagonal}
} }

View File

@ -76,6 +76,21 @@ public class GenericShape implements Shape {
@Override @Override
public Interactor applyStateMonitor(State state, Listener listener, Model model) { 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; return null;
} }
@ -84,6 +99,11 @@ public class GenericShape implements Shape {
int max = Math.max(inputs, outputs); int max = Math.max(inputs, outputs);
int height = (max - 1) * SIZE + SIZE2; 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; if (symmetric && ((inputs & 1) == 0)) height += SIZE;
graphic.drawPolygon(new Polygon(true) graphic.drawPolygon(new Polygon(true)

View File

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

View File

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