From 688db05fc1691fc33ca27ac7a33a9ad35e7cf4fb Mon Sep 17 00:00:00 2001 From: hneemann Date: Sat, 9 Apr 2016 11:11:41 +0200 Subject: [PATCH] added data view in circuit area. made shapes and ShapeFactory more consistent. --- src/main/dig/sequential/Counter_JK.dig | 351 ++++++++++++++++++ src/main/dig/sequential/Counter_T.dig | 214 +++++++++++ src/main/dig/sequential/T.dig | 227 +++++++++++ .../java/de/neemann/digital/core/Model.java | 2 +- .../digital/core/element/AttributeKey.java | 1 + .../neemann/digital/core/element/Element.java | 2 +- .../core/element/ElementAttributes.java | 5 + .../neemann/digital/core/wiring/Splitter.java | 2 +- .../digital/draw/library/ElementLibrary.java | 2 + .../digital/draw/model/ModelDescription.java | 12 +- .../digital/draw/shapes/BreakShape.java | 5 +- .../digital/draw/shapes/ClockShape.java | 5 +- .../digital/draw/shapes/ConstShape.java | 6 +- .../digital/draw/shapes/DataShape.java | 69 ++++ .../digital/draw/shapes/DemuxerShape.java | 8 +- .../digital/draw/shapes/DriverShape.java | 6 +- .../digital/draw/shapes/InputShape.java | 5 +- .../neemann/digital/draw/shapes/LEDShape.java | 10 +- .../digital/draw/shapes/MuxerShape.java | 8 +- .../digital/draw/shapes/OutputShape.java | 5 +- .../digital/draw/shapes/ProbeShape.java | 5 +- .../digital/draw/shapes/ResetShape.java | 5 +- .../digital/draw/shapes/SevenSegHexShape.java | 11 +- .../digital/draw/shapes/SevenSegShape.java | 7 +- .../digital/draw/shapes/SevenShape.java | 8 +- .../de/neemann/digital/draw/shapes/Shape.java | 15 +- .../digital/draw/shapes/ShapeFactory.java | 32 +- .../digital/draw/shapes/SplitterShape.java | 6 +- .../java/de/neemann/digital/gui/Main.java | 1 + .../gui/components/data/DataSample.java | 4 +- .../digital/gui/components/data/DataSet.java | 21 ++ .../gui/components/data/DataSetDialog.java | 23 +- .../gui/components/data/DataSetObserver.java | 41 ++ .../gui/components/data/DummyElement.java | 46 +++ src/main/resources/lang/lang_de.properties | 2 +- src/main/resources/lang/lang_en.properties | 1 + 36 files changed, 1089 insertions(+), 84 deletions(-) create mode 100644 src/main/dig/sequential/Counter_JK.dig create mode 100644 src/main/dig/sequential/Counter_T.dig create mode 100644 src/main/dig/sequential/T.dig create mode 100644 src/main/java/de/neemann/digital/draw/shapes/DataShape.java create mode 100644 src/main/java/de/neemann/digital/gui/components/data/DataSetObserver.java create mode 100644 src/main/java/de/neemann/digital/gui/components/data/DummyElement.java diff --git a/src/main/dig/sequential/Counter_JK.dig b/src/main/dig/sequential/Counter_JK.dig new file mode 100644 index 000000000..4df4d255d --- /dev/null +++ b/src/main/dig/sequential/Counter_JK.dig @@ -0,0 +1,351 @@ + + + 1 + + + Out + + + rotation + + + + + 3 + + + JK_FF + + + valueIsProbe + true + + + Label + Q_0 + + + + 0 + + + JK_FF + + + valueIsProbe + true + + + Label + Q_1 + + + Default + 1 + + + + 0 + + + JK_FF + + + valueIsProbe + true + + + Label + Q_2 + + + Default + 1 + + + + 0 + + + JK_FF + + + valueIsProbe + true + + + Label + Q_3 + + + Default + 1 + + + + 0 + + + And + + + 0 + + + And + + + 0 + + + Const + + + 0 + + + Clock + + + Label + C + + + + 0 + + + Out + + + rotation + + + + + 3 + + + Out + + + rotation + + + + + 3 + + + Out + + + rotation + + + + + 3 + + + Data + + + microStep + true + + + Label + Data + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C + Q_0 + Q_1 + Q_2 + Q_3 + + \ No newline at end of file diff --git a/src/main/dig/sequential/Counter_T.dig b/src/main/dig/sequential/Counter_T.dig new file mode 100644 index 000000000..8b6b2e43d --- /dev/null +++ b/src/main/dig/sequential/Counter_T.dig @@ -0,0 +1,214 @@ + + + 1 + + + Out + + + rotation + + + + + 3 + + + Clock + + + Label + C + + + Frequency + 2 + + + + 0 + + + Out + + + rotation + + + + + 3 + + + Out + + + rotation + + + + + 3 + + + Out + + + rotation + + + + + 3 + + + T_FF + + + valueIsProbe + true + + + Label + Q_0 + + + + 0 + + + T_FF + + + valueIsProbe + true + + + Label + Q_1 + + + + 0 + + + T_FF + + + valueIsProbe + true + + + Label + Q_2 + + + + 0 + + + T_FF + + + valueIsProbe + true + + + Label + Q_3 + + + + 0 + + + Data + + + microStep + true + + + Label + Data + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/dig/sequential/T.dig b/src/main/dig/sequential/T.dig new file mode 100644 index 000000000..ed0988741 --- /dev/null +++ b/src/main/dig/sequential/T.dig @@ -0,0 +1,227 @@ + + + 1 + + + And + + + 0 + + + Not + + + 0 + + + And + + + 0 + + + And + + + 0 + + + NOr + + + 0 + + + NOr + + + 0 + + + Out + + + Label + Q + + + + 0 + + + Out + + + Label + ~Q + + + + 0 + + + Delay + + + 0 + + + In + + + Label + C + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C + J + K + Dif + Q + ~Q + + \ No newline at end of file diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index fc4f924c6..706157108 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -406,7 +406,7 @@ public class Model { * @param name the name of the Signal * @param value the signals value */ - private Signal(String name, ObservableValue value) { + public Signal(String name, ObservableValue value) { this.name = name; this.value = value; } diff --git a/src/main/java/de/neemann/digital/core/element/AttributeKey.java b/src/main/java/de/neemann/digital/core/element/AttributeKey.java index c2c291794..ff09fe970 100644 --- a/src/main/java/de/neemann/digital/core/element/AttributeKey.java +++ b/src/main/java/de/neemann/digital/core/element/AttributeKey.java @@ -33,6 +33,7 @@ public class AttributeKey { public static final AttributeKey ShowDataTable = new AttributeKey<>("showDataTable", Lang.get("key_showDataTable"), false); public static final AttributeKey ShowDataGraph = new AttributeKey<>("showDataGraph", Lang.get("key_showDataGraph"), false); public static final AttributeKey StartTimer = new AttributeKey<>("startTimer", Lang.get("key_startClock"), false); + public static final AttributeKey MicroStep = new AttributeKey<>("microStep", Lang.get("key_microStep"), false); private final String key; private final VALUE def; diff --git a/src/main/java/de/neemann/digital/core/element/Element.java b/src/main/java/de/neemann/digital/core/element/Element.java index 2c44ac5ae..2aeb839da 100644 --- a/src/main/java/de/neemann/digital/core/element/Element.java +++ b/src/main/java/de/neemann/digital/core/element/Element.java @@ -40,7 +40,7 @@ public interface Element { /** * Is called after registerNodes is called on all Elements. */ - default void init() { + default void init(Model model) { } } diff --git a/src/main/java/de/neemann/digital/core/element/ElementAttributes.java b/src/main/java/de/neemann/digital/core/element/ElementAttributes.java index 620e38bce..9ecc52904 100644 --- a/src/main/java/de/neemann/digital/core/element/ElementAttributes.java +++ b/src/main/java/de/neemann/digital/core/element/ElementAttributes.java @@ -84,6 +84,10 @@ public class ElementAttributes { return get(AttributeKey.Bits); } + public String getLabel() { + return get(AttributeKey.Label); + } + public ElementAttributes setBits(int bits) { set(AttributeKey.Bits, bits); return this; @@ -116,4 +120,5 @@ public class ElementAttributes { attributes = new HashMap<>(); attributes.put(fileKey, file.getPath()); } + } diff --git a/src/main/java/de/neemann/digital/core/wiring/Splitter.java b/src/main/java/de/neemann/digital/core/wiring/Splitter.java index 11fac76e8..db6f8a99c 100644 --- a/src/main/java/de/neemann/digital/core/wiring/Splitter.java +++ b/src/main/java/de/neemann/digital/core/wiring/Splitter.java @@ -152,7 +152,7 @@ public class Splitter implements Element { } @Override - public void init() { + public void init(Model m) { for (ObservableValue v : inputs) v.hasChanged(); } diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index fcd82eb76..657f2bd87 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -16,6 +16,7 @@ import de.neemann.digital.core.io.Out; import de.neemann.digital.core.io.Probe; import de.neemann.digital.core.memory.*; import de.neemann.digital.core.wiring.*; +import de.neemann.digital.gui.components.data.DummyElement; import de.neemann.digital.gui.components.terminal.Terminal; import de.neemann.digital.lang.Lang; @@ -54,6 +55,7 @@ public class ElementLibrary implements Iterable add(Out.SEVENDESCRIPTION, menu); add(Out.SEVENHEXDESCRIPTION, menu); add(Terminal.DESCRIPTION, menu); + add(DummyElement.DATADESCRIPTION, menu); menu = Lang.get("lib_mux"); add(Multiplexer.DESCRIPTION, menu); diff --git a/src/main/java/de/neemann/digital/draw/model/ModelDescription.java b/src/main/java/de/neemann/digital/draw/model/ModelDescription.java index b1879766c..7b0685fd4 100644 --- a/src/main/java/de/neemann/digital/draw/model/ModelDescription.java +++ b/src/main/java/de/neemann/digital/draw/model/ModelDescription.java @@ -24,10 +24,10 @@ import java.util.*; */ public class ModelDescription implements Iterable { + private final Circuit circuit; private final NetList netList; private final ArrayList entries; private final HashMap ioMap; - private HashMap map; /** * Creates the ModelDescription. @@ -69,6 +69,7 @@ public class ModelDescription implements Iterable { * @throws NodeException NodeException */ public ModelDescription(Circuit circuit, ElementLibrary library, boolean readAsCustom, String fileName, NetList netList) throws PinException, NodeException { + this.circuit = circuit; this.netList = netList; entries = new ArrayList<>(); if (readAsCustom) @@ -176,8 +177,10 @@ public class ModelDescription implements Iterable { for (ModelEntry e : entries) e.getElement().registerNodes(m); - for (ModelEntry e : entries) - e.getElement().init(); + for (ModelEntry e : entries) { + e.getElement().init(m); + e.getVisualElement().getShape().registerModel(this, m, e); + } return m; } @@ -231,4 +234,7 @@ public class ModelDescription implements Iterable { return entr; } + public Circuit getCircuit() { + return circuit; + } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/BreakShape.java b/src/main/java/de/neemann/digital/draw/shapes/BreakShape.java index f6e9e6f56..19e1463b0 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/BreakShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/BreakShape.java @@ -1,6 +1,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -20,8 +21,8 @@ public class BreakShape implements Shape { private static final Vector D2 = new Vector(SIZEQ, SIZEQ); private final String label; - public BreakShape(String label) { - this.label = label; + public BreakShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/ClockShape.java b/src/main/java/de/neemann/digital/draw/shapes/ClockShape.java index b318d8d1d..c54dafc22 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ClockShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ClockShape.java @@ -3,6 +3,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -21,8 +22,8 @@ public class ClockShape implements Shape { private final String label; - public ClockShape(String label) { - this.label = label; + public ClockShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/ConstShape.java b/src/main/java/de/neemann/digital/draw/shapes/ConstShape.java index b3a2b5102..666ccba9e 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ConstShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ConstShape.java @@ -2,6 +2,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -17,8 +19,8 @@ public class ConstShape implements Shape { private String value; - public ConstShape(long value) { - this.value = ObservableValue.getHexString(value); + public ConstShape(ElementAttributes attr) { + this.value = ObservableValue.getHexString(attr.get(AttributeKey.Value)); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/DataShape.java b/src/main/java/de/neemann/digital/draw/shapes/DataShape.java new file mode 100644 index 000000000..c4f2464e0 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/shapes/DataShape.java @@ -0,0 +1,69 @@ +package de.neemann.digital.draw.shapes; + +import de.neemann.digital.core.Model; +import de.neemann.digital.core.ModelEvent; +import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.draw.elements.IOState; +import de.neemann.digital.draw.elements.Pins; +import de.neemann.digital.draw.graphics.Graphic; +import de.neemann.digital.draw.model.ModelDescription; +import de.neemann.digital.draw.model.ModelEntry; +import de.neemann.digital.gui.components.OrderMerger; +import de.neemann.digital.gui.components.data.DataSet; +import de.neemann.digital.gui.components.data.DataSetObserver; + +import java.util.ArrayList; + +/** + * Shape which shows the data graph inside the models circuit area. + * + * @author hneemann + */ +public class DataShape implements Shape { + + private final ModelEvent.Event type; + private DataSet dataSet; + + public DataShape(ElementAttributes attr) { + if (attr.get(AttributeKey.MicroStep)) + type = ModelEvent.Event.MICROSTEP; + else + type = ModelEvent.Event.STEP; + } + + @Override + public Pins getPins() { + return new Pins(); + } + + @Override + public Interactor applyStateMonitor(IOState ioState, Observer guiObserver) { + return null; + } + + @Override + public void drawTo(Graphic graphic, boolean heighLight) { + if (dataSet == null) { + dataSet = new DataSet(); + } + dataSet.drawTo(graphic, false); + } + + @Override + public void registerModel(ModelDescription modelDescription, Model model, ModelEntry element) { + ArrayList signals = model.getSignalsCopy(); + new OrderMerger(modelDescription.getCircuit().getMeasurementOrdering()) { + @Override + public boolean equals(Model.Signal a, String b) { + return a.getName().equals(b); + } + }.order(signals); + + dataSet = new DataSet(signals); + + DataSetObserver dataSetObserver = new DataSetObserver(type, dataSet); + model.addObserver(dataSetObserver); + } +} diff --git a/src/main/java/de/neemann/digital/draw/shapes/DemuxerShape.java b/src/main/java/de/neemann/digital/draw/shapes/DemuxerShape.java index 74b19e8b0..81dea9f3d 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/DemuxerShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/DemuxerShape.java @@ -1,6 +1,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -18,10 +20,10 @@ public class DemuxerShape implements Shape { private final int height; private Pins pins; - public DemuxerShape(int selectorBits, boolean hasInput, boolean flip) { + public DemuxerShape(ElementAttributes attr, boolean hasInput) { this.hasInput = hasInput; - this.flip = flip; - outputCount = 1 << selectorBits; + this.flip = attr.get(AttributeKey.FlipSelPositon); + outputCount = 1 << attr.get(AttributeKey.SelectorBits); height = hasInput || (outputCount <= 2) ? outputCount * SIZE : (outputCount - 1) * SIZE; } diff --git a/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java b/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java index c47de763f..fb648573f 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java @@ -1,6 +1,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -19,8 +21,8 @@ public class DriverShape implements Shape { private final boolean bottom; private Pins pins; - public DriverShape(boolean bottom) { - this.bottom = bottom; + public DriverShape(ElementAttributes attr) { + this.bottom = attr.get(AttributeKey.FlipSelPositon); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/InputShape.java b/src/main/java/de/neemann/digital/draw/shapes/InputShape.java index 15049e2fd..8283c49c0 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/InputShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/InputShape.java @@ -3,6 +3,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -24,8 +25,8 @@ public class InputShape implements Shape { private final String label; private IOState ioState; - public InputShape(String label) { - this.label = label; + public InputShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/LEDShape.java b/src/main/java/de/neemann/digital/draw/shapes/LEDShape.java index 23b2d37d0..cd44264a8 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/LEDShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/LEDShape.java @@ -2,6 +2,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -10,8 +12,6 @@ import de.neemann.digital.draw.graphics.Orientation; import de.neemann.digital.draw.graphics.Style; import de.neemann.digital.draw.graphics.Vector; -import java.awt.*; - import static de.neemann.digital.draw.shapes.OutputShape.SIZE; /** @@ -24,9 +24,9 @@ public class LEDShape implements Shape { private Style onStyle; private IOState ioState; - public LEDShape(String label, Color color) { - this.label = label; - onStyle = new Style(1, true, color); + public LEDShape(ElementAttributes attr) { + this.label = attr.getLabel(); + onStyle = new Style(1, true, attr.get(AttributeKey.Color)); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/MuxerShape.java b/src/main/java/de/neemann/digital/draw/shapes/MuxerShape.java index bc2278459..c0ab4d584 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/MuxerShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/MuxerShape.java @@ -1,6 +1,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -16,9 +18,9 @@ public class MuxerShape implements Shape { private final boolean flip; private Pins pins; - public MuxerShape(int selectorBits, boolean flip) { - this.flip = flip; - this.inputCount = 1 << selectorBits; + public MuxerShape(ElementAttributes attr) { + this.flip = attr.get(AttributeKey.FlipSelPositon); + this.inputCount = 1 << attr.get(AttributeKey.SelectorBits); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/OutputShape.java b/src/main/java/de/neemann/digital/draw/shapes/OutputShape.java index 2447dfe0f..616586e61 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/OutputShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/OutputShape.java @@ -2,6 +2,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -20,8 +21,8 @@ public class OutputShape implements Shape { private final String label; private IOState ioState; - public OutputShape(String label) { - this.label = label; + public OutputShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java b/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java index 331b0d2de..1f11e1b65 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ProbeShape.java @@ -1,6 +1,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -18,8 +19,8 @@ public class ProbeShape implements Shape { private IOState ioState; private int bits; - public ProbeShape(String label) { - this.label = label; + public ProbeShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/ResetShape.java b/src/main/java/de/neemann/digital/draw/shapes/ResetShape.java index 46de05b4c..a884394d5 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ResetShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ResetShape.java @@ -1,6 +1,7 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; @@ -15,8 +16,8 @@ public class ResetShape implements Shape { private final String label; - public ResetShape(String label) { - this.label = label; + public ResetShape(ElementAttributes attr) { + this.label = attr.getLabel(); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java index 98fddbf4a..f76665865 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenSegHexShape.java @@ -2,26 +2,25 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; import de.neemann.digital.draw.graphics.Style; import de.neemann.digital.draw.graphics.Vector; -import java.awt.*; - import static de.neemann.digital.draw.shapes.GenericShape.SIZE; /** * @author hneemann */ public class SevenSegHexShape extends SevenShape { - private static final int[] table = new int[]{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; + private static final int[] TABLE = new int[]{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; private Pins pins; private ObservableValue input; - public SevenSegHexShape(String label, Color color) { - super(label, color); + public SevenSegHexShape(ElementAttributes attr) { + super(attr); } @Override @@ -30,7 +29,7 @@ public class SevenSegHexShape extends SevenShape { return onStyle; int v = (int) input.getValueIgnoreBurn() & 0xf; - v = table[v]; + v = TABLE[v]; if ((v & (1 << i)) != 0) return onStyle; else diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java index 02a368417..4c831e45f 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenSegShape.java @@ -2,14 +2,13 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; import de.neemann.digital.draw.elements.Pins; import de.neemann.digital.draw.graphics.Style; import de.neemann.digital.draw.graphics.Vector; -import java.awt.*; - import static de.neemann.digital.draw.shapes.GenericShape.SIZE; /** @@ -19,8 +18,8 @@ public class SevenSegShape extends SevenShape { private ObservableValue[] inputs; private Pins pins; - public SevenSegShape(String label, Color color) { - super(label, color); + public SevenSegShape(ElementAttributes attr) { + super(attr); } @Override diff --git a/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java b/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java index 86c635be4..f922a0c0e 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SevenShape.java @@ -1,5 +1,7 @@ package de.neemann.digital.draw.shapes; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.draw.graphics.Graphic; import de.neemann.digital.draw.graphics.Polygon; import de.neemann.digital.draw.graphics.Style; @@ -23,9 +25,9 @@ public abstract class SevenShape implements Shape { protected final Style onStyle; protected final Style offStyle; - public SevenShape(String label, Color color) { - this.label = label; - onStyle = new Style(8, true, color); + public SevenShape(ElementAttributes attr) { + this.label = attr.getLabel(); + onStyle = new Style(8, true, attr.get(AttributeKey.Color)); offStyle = new Style(8, true, new Color(230, 230, 230)); } diff --git a/src/main/java/de/neemann/digital/draw/shapes/Shape.java b/src/main/java/de/neemann/digital/draw/shapes/Shape.java index 8c7be91e9..844498943 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/Shape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/Shape.java @@ -1,8 +1,11 @@ package de.neemann.digital.draw.shapes; +import de.neemann.digital.core.Model; import de.neemann.digital.core.Observer; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pins; +import de.neemann.digital.draw.model.ModelDescription; +import de.neemann.digital.draw.model.ModelEntry; /** * @author hneemann @@ -23,7 +26,7 @@ public interface Shape extends Drawable { * shape can register the guiObserver to one of the the input or output ObservableValues. * To access the actual state while drawing, the Shape needs to store the IOState in a member * variable. - * + *

* If the shape returns an interactor, this interactors clicked method is called if the * shape is clicked in the running mode. * @@ -33,4 +36,14 @@ public interface Shape extends Drawable { */ Interactor applyStateMonitor(IOState ioState, Observer guiObserver); + /** + * Allows the shape to make its drawing dependent of the model. + * It is used by {@link DataShape} to create and show the data graph. + * + * @param modelDescription the models description + * @param model the model itself + * @param element the ModelElement this shape belongs to + */ + default void registerModel(ModelDescription modelDescription, Model model, ModelEntry element) { + } } diff --git a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java index 347051dfa..7efddc3ce 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java +++ b/src/main/java/de/neemann/digital/draw/shapes/ShapeFactory.java @@ -15,6 +15,7 @@ import de.neemann.digital.core.memory.RAMSinglePort; import de.neemann.digital.core.wiring.*; import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.gui.LibrarySelector; +import de.neemann.digital.gui.components.data.DummyElement; import de.neemann.digital.lang.Lang; import java.util.HashMap; @@ -42,24 +43,25 @@ public final class ShapeFactory { map.put(RAMDualPort.DESCRIPTION.getName(), attr -> new RAMShape("RAM", RAMDualPort.DESCRIPTION.getInputNames(attr), outputInfos(RAMDualPort.DESCRIPTION, attr), attr.get(AttributeKey.Label))); map.put(RAMSinglePort.DESCRIPTION.getName(), attr -> new RAMShape("RAM", RAMSinglePort.DESCRIPTION.getInputNames(attr), outputInfos(RAMSinglePort.DESCRIPTION, attr), attr.get(AttributeKey.Label))); - map.put(In.DESCRIPTION.getName(), attr -> new InputShape(attr.get(AttributeKey.Label))); - map.put(Reset.DESCRIPTION.getName(), attr -> new ResetShape(attr.get(AttributeKey.Label))); - map.put(Const.DESCRIPTION.getName(), attr -> new ConstShape(attr.get(AttributeKey.Value))); - map.put(Out.DESCRIPTION.getName(), attr -> new OutputShape(attr.get(AttributeKey.Label))); - map.put(Out.LEDDESCRIPTION.getName(), attr -> new LEDShape(attr.get(AttributeKey.Label), attr.get(AttributeKey.Color))); - map.put(Probe.DESCRIPTION.getName(), attr -> new ProbeShape(attr.get(AttributeKey.Label))); - map.put(Clock.DESCRIPTION.getName(), attr -> new ClockShape(attr.get(AttributeKey.Label))); - map.put(Out.SEVENDESCRIPTION.getName(), attr -> new SevenSegShape(attr.get(AttributeKey.Label), attr.get(AttributeKey.Color))); - map.put(Out.SEVENHEXDESCRIPTION.getName(), attr -> new SevenSegHexShape(attr.get(AttributeKey.Label), attr.get(AttributeKey.Color))); + map.put(In.DESCRIPTION.getName(), InputShape::new); + map.put(Reset.DESCRIPTION.getName(), ResetShape::new); + map.put(Const.DESCRIPTION.getName(), ConstShape::new); + map.put(Out.DESCRIPTION.getName(), OutputShape::new); + map.put(Out.LEDDESCRIPTION.getName(), LEDShape::new); + map.put(Probe.DESCRIPTION.getName(), ProbeShape::new); + map.put(Clock.DESCRIPTION.getName(), ClockShape::new); + map.put(Out.SEVENDESCRIPTION.getName(), SevenSegShape::new); + map.put(Out.SEVENHEXDESCRIPTION.getName(), SevenSegHexShape::new); + map.put(DummyElement.DATADESCRIPTION.getName(), DataShape::new); - map.put(Break.DESCRIPTION.getName(), attributes -> new BreakShape(attributes.get(AttributeKey.Label))); + map.put(Break.DESCRIPTION.getName(), BreakShape::new); - map.put(Multiplexer.DESCRIPTION.getName(), attr -> new MuxerShape(attr.get(AttributeKey.SelectorBits), attr.get(AttributeKey.FlipSelPositon))); - map.put(Demultiplexer.DESCRIPTION.getName(), attr -> new DemuxerShape(attr.get(AttributeKey.SelectorBits), true, attr.get(AttributeKey.FlipSelPositon))); - map.put(Decoder.DESCRIPTION.getName(), attr -> new DemuxerShape(attr.get(AttributeKey.SelectorBits), false, attr.get(AttributeKey.FlipSelPositon))); + map.put(Multiplexer.DESCRIPTION.getName(), MuxerShape::new); + map.put(Demultiplexer.DESCRIPTION.getName(), attr -> new DemuxerShape(attr, true)); + map.put(Decoder.DESCRIPTION.getName(), attr -> new DemuxerShape(attr, false)); - map.put(Splitter.DESCRIPTION.getName(), attr -> new SplitterShape(attr.get(AttributeKey.InputSplit), attr.get(AttributeKey.OutputSplit))); - map.put(Driver.DESCRIPTION.getName(), attr -> new DriverShape(attr.get(AttributeKey.FlipSelPositon))); + map.put(Splitter.DESCRIPTION.getName(), SplitterShape::new); + map.put(Driver.DESCRIPTION.getName(), DriverShape::new); } private OutputPinInfo[] outputInfos(ElementTypeDescription description, ElementAttributes attributes) { diff --git a/src/main/java/de/neemann/digital/draw/shapes/SplitterShape.java b/src/main/java/de/neemann/digital/draw/shapes/SplitterShape.java index 95d75207b..21c6cb5bb 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/SplitterShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/SplitterShape.java @@ -2,6 +2,8 @@ package de.neemann.digital.draw.shapes; import de.neemann.digital.core.BitsException; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.wiring.Splitter; import de.neemann.digital.draw.elements.IOState; import de.neemann.digital.draw.elements.Pin; @@ -20,7 +22,9 @@ public class SplitterShape implements Shape { private final int length; private Pins pins; - public SplitterShape(String inputDef, String outputDef) throws BitsException { + public SplitterShape(ElementAttributes attr) throws BitsException { + String inputDef = attr.get(AttributeKey.InputSplit); + String outputDef = attr.get(AttributeKey.OutputSplit); inputs = new Splitter.Ports(inputDef).getNames(); outputs = new Splitter.Ports(outputDef).getNames(); length = (Math.max(inputs.length, outputs.length) - 1) * SIZE + 2; diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index d5036703a..4b082e960 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -550,6 +550,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E @Override public void hasChanged() { try { + model.fireManualChangeEvent(); model.doStep(); circuitComponent.repaint(); } catch (NodeException | RuntimeException e) { diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSample.java b/src/main/java/de/neemann/digital/gui/components/data/DataSample.java index a6d9ab2ce..b03963bb5 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/DataSample.java +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSample.java @@ -56,9 +56,11 @@ public class DataSample { * * @param i the index of the value * @param value the value + * @return this for chained calls */ - public void setValue(int i, long value) { + public DataSample setValue(int i, long value) { values[i] = value; + return this; } /** diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSet.java b/src/main/java/de/neemann/digital/gui/components/data/DataSet.java index 33c266624..31278cf08 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/DataSet.java +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSet.java @@ -24,6 +24,23 @@ public class DataSet implements Iterable, Drawable { private DataSample min; private DataSample max; + /** + * Creates a simple dummy DataSet used for creating the DataShape + */ + public DataSet() { + this(createDummy()); + add(new DataSample(0, signalSize())); + add(new DataSample(1, signalSize()).setValue(1, 1)); + } + + private static ArrayList createDummy() { + ArrayList list = new ArrayList<>(); + list.add(new Model.Signal("A", null)); + list.add(new Model.Signal("B", null)); + list.add(new Model.Signal("C", null)); + return list; + } + /** * Creates a new instance * @@ -173,4 +190,8 @@ public class DataSet implements Iterable, Drawable { public int getGraphicHeight() { return signalSize() * (SIZE + SEP) + 2 * BORDER; } + + public ArrayList getSignals() { + return signals; + } } diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java index 7a13e1760..1ce8bb9df 100644 --- a/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSetDialog.java @@ -19,12 +19,10 @@ import java.util.List; * @author hneemann */ public class DataSetDialog extends JDialog implements ModelStateObserver { - private final ModelEvent.Event type; private final ArrayList signals; private final DataSetComponent dsc; - private DataSample manualSample; - private int maintime; private DataSet dataSet; + private DataSetObserver dataSetObserver; /** * Creates a new instance @@ -38,7 +36,6 @@ public class DataSetDialog extends JDialog implements ModelStateObserver { super(owner, Lang.get("win_measures"), false); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setAlwaysOnTop(true); - this.type = type; signals = model.getSignalsCopy(); new OrderMerger(ordering) { @@ -50,6 +47,8 @@ public class DataSetDialog extends JDialog implements ModelStateObserver { dataSet = new DataSet(signals); + dataSetObserver = new DataSetObserver(type, dataSet); + dsc = new DataSetComponent(dataSet); JScrollPane scrollPane = new JScrollPane(dsc); getContentPane().add(scrollPane); @@ -75,21 +74,7 @@ public class DataSetDialog extends JDialog implements ModelStateObserver { @Override public void handleEvent(ModelEvent event) { - if (event.getType() == ModelEvent.Event.MANUALCHANGE) { - if (manualSample == null) - manualSample = new DataSample(maintime, signals.size()); - manualSample.fillWith(signals); - } - - if (event.getType() == type) { - if (manualSample != null) { - dataSet.add(manualSample); - manualSample = null; - maintime++; - } - dataSet.add(new DataSample(maintime, signals.size()).fillWith(signals)); - maintime++; - } + dataSetObserver.handleEvent(event); dsc.revalidate(); dsc.repaint(); } diff --git a/src/main/java/de/neemann/digital/gui/components/data/DataSetObserver.java b/src/main/java/de/neemann/digital/gui/components/data/DataSetObserver.java new file mode 100644 index 000000000..8ba931670 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/data/DataSetObserver.java @@ -0,0 +1,41 @@ +package de.neemann.digital.gui.components.data; + +import de.neemann.digital.core.ModelEvent; +import de.neemann.digital.core.ModelStateObserver; + +/** + * @author hneemann + */ +public class DataSetObserver implements ModelStateObserver { + + private final DataSet dataSet; + private final ModelEvent.Event type; + + private DataSample manualSample; + private int maintime; + + public DataSetObserver(ModelEvent.Event type, DataSet dataSet) { + this.type = type; + this.dataSet = dataSet; + } + + @Override + public void handleEvent(ModelEvent event) { + if (event.getType() == ModelEvent.Event.MANUALCHANGE) { + if (manualSample == null) + manualSample = new DataSample(maintime, dataSet.signalSize()); + manualSample.fillWith(dataSet.getSignals()); + } + + if (event.getType() == type) { + if (manualSample != null) { + dataSet.add(manualSample); + manualSample = null; + maintime++; + } + dataSet.add(new DataSample(maintime, dataSet.signalSize()).fillWith(dataSet.getSignals())); + maintime++; + } + } + +} diff --git a/src/main/java/de/neemann/digital/gui/components/data/DummyElement.java b/src/main/java/de/neemann/digital/gui/components/data/DummyElement.java new file mode 100644 index 000000000..a0fb3e0dc --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/data/DummyElement.java @@ -0,0 +1,46 @@ +package de.neemann.digital.gui.components.data; + +import de.neemann.digital.core.Model; +import de.neemann.digital.core.NodeException; +import de.neemann.digital.core.ObservableValue; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementAttributes; +import de.neemann.digital.core.element.ElementTypeDescription; + +/** + * Only a placeholder. + * Has no connections to the model! + * + * @author hneemann + */ +public class DummyElement implements Element { + + /** + * The DataElement description + */ + public static final ElementTypeDescription DATADESCRIPTION = new ElementTypeDescription("Data", DummyElement.class) + .addAttribute(AttributeKey.MicroStep); + + /** + * Creates a new dummy element + * + * @param attr the attributes + */ + public DummyElement(ElementAttributes attr) { + } + + @Override + public void setInputs(ObservableValue... inputs) throws NodeException { + } + + @Override + public ObservableValue[] getOutputs() { + return new ObservableValue[0]; + } + + @Override + public void registerNodes(Model model) { + } + +} diff --git a/src/main/resources/lang/lang_de.properties b/src/main/resources/lang/lang_de.properties index 7e0354f86..4253d55d3 100644 --- a/src/main/resources/lang/lang_de.properties +++ b/src/main/resources/lang/lang_de.properties @@ -36,7 +36,7 @@ key_showListing=Zeige Listing an, wenn verf\u00FCgbar key_showDataTable=Zeige Messwertetabelle key_showDataGraph=Zeige Messwertegraph key_startClock=Starte den Takt - +key_microStep=Zeige Mikroschritte rot_0=0\u00B0 rot_90=90\u00B0 diff --git a/src/main/resources/lang/lang_en.properties b/src/main/resources/lang/lang_en.properties index 8cbefbd3b..2161354c7 100644 --- a/src/main/resources/lang/lang_en.properties +++ b/src/main/resources/lang/lang_en.properties @@ -36,6 +36,7 @@ key_showListing=Show list file if available key_showDataTable=Show measurement values key_showDataGraph=Show measurement graph key_startClock=Start timer +key_microStep=Show micro steps rot_0=0\u00B0 rot_90=90\u00B0