From 6074a02724c37f9eeaf321bb17911ec030c9881a Mon Sep 17 00:00:00 2001 From: hneemann Date: Mon, 28 Mar 2016 23:49:47 +0200 Subject: [PATCH] Started to implement a Break-element --- .../de/neemann/digital/core/ModelEvent.java | 14 +++- .../digital/core/element/AttributeKey.java | 1 + .../de/neemann/digital/core/wiring/Break.java | 61 ++++++++++++++ .../de/neemann/digital/core/wiring/Clock.java | 82 +++++++++++-------- .../java/de/neemann/digital/gui/Main.java | 12 +++ src/main/resources/lang/lang_de.properties | 5 ++ src/main/resources/lang/lang_en.properties | 7 +- 7 files changed, 148 insertions(+), 34 deletions(-) create mode 100644 src/main/java/de/neemann/digital/core/wiring/Break.java diff --git a/src/main/java/de/neemann/digital/core/ModelEvent.java b/src/main/java/de/neemann/digital/core/ModelEvent.java index 76fc1dcd8..bb61db46c 100644 --- a/src/main/java/de/neemann/digital/core/ModelEvent.java +++ b/src/main/java/de/neemann/digital/core/ModelEvent.java @@ -1,5 +1,6 @@ package de.neemann.digital.core; +import de.neemann.digital.core.wiring.Break; import de.neemann.digital.core.wiring.Clock; import java.util.ArrayList; @@ -12,10 +13,11 @@ public class ModelEvent { public static final ModelEvent STEP = new ModelEvent(Event.STEP); - public enum Event {STARTED, STOPPED, FETCHCLOCK, STEP} + public enum Event {STARTED, STOPPED, FETCHCLOCK, FETCHBREAK, STEP} private final Event event; private ArrayList clocks; + private ArrayList breaks; public ModelEvent(Event event) { this.event = event; @@ -34,4 +36,14 @@ public class ModelEvent { public ArrayList getClocks() { return clocks; } + + public void registerBreak(Break aBreak) { + if (breaks == null) + breaks = new ArrayList(); + breaks.add(aBreak); + } + + public ArrayList getBreaks() { + return breaks; + } } 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 4d9577a11..54f12760b 100644 --- a/src/main/java/de/neemann/digital/core/element/AttributeKey.java +++ b/src/main/java/de/neemann/digital/core/element/AttributeKey.java @@ -24,6 +24,7 @@ public class AttributeKey { public static final AttributeKey FlipSelPositon = new AttributeKey<>("flipSelPos", Lang.get("key_flipSelPos"), false); public static final AttributeKey Rotate = new AttributeKey<>("rotation", Lang.get("key_rotation"), new Rotation(0)); public static final AttributeKey Width = new AttributeKey<>("Width", Lang.get("key_width"), 3); + public static final AttributeKey Cycles = new AttributeKey<>("Cycles", Lang.get("key_cycles"), 100000); private final String key; diff --git a/src/main/java/de/neemann/digital/core/wiring/Break.java b/src/main/java/de/neemann/digital/core/wiring/Break.java new file mode 100644 index 000000000..6156a8f32 --- /dev/null +++ b/src/main/java/de/neemann/digital/core/wiring/Break.java @@ -0,0 +1,61 @@ +package de.neemann.digital.core.wiring; + +import de.neemann.digital.core.*; +import de.neemann.digital.core.element.AttributeKey; +import de.neemann.digital.core.element.Element; +import de.neemann.digital.core.element.ElementTypeDescription; + +/** + * @author hneemann + */ +public class Break implements Element { + + public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Break.class, "brk") + .addAttribute(AttributeKey.Rotate) + .addAttribute(AttributeKey.Label) + .addAttribute(AttributeKey.Cycles); + + + private ObservableValue input; + + @Override + public void setInputs(ObservableValue... inputs) throws NodeException { + input = inputs[0].checkBits(1, null); + } + + public ObservableValue getInput() { + return input; + } + + @Override + public ObservableValue[] getOutputs() { + return new ObservableValue[0]; + } + + @Override + public void registerNodes(Model model) { + model.addObserver(new MyModelStateObserver(model, this)); + } + + private static class MyModelStateObserver implements ModelStateObserver { + private final Model model; + private final Break aBreak; + + public MyModelStateObserver(Model model, Break aBreak) { + this.model = model; + this.aBreak = aBreak; + } + + @Override + public void handleEvent(ModelEvent event) { + switch (event.getType()) { + case FETCHBREAK: + event.registerBreak(aBreak); + break; + case STARTED: + model.removeObserver(this); + break; + } + } + } +} diff --git a/src/main/java/de/neemann/digital/core/wiring/Clock.java b/src/main/java/de/neemann/digital/core/wiring/Clock.java index b577dd3db..e2edcfa2d 100644 --- a/src/main/java/de/neemann/digital/core/wiring/Clock.java +++ b/src/main/java/de/neemann/digital/core/wiring/Clock.java @@ -22,11 +22,13 @@ public class Clock implements Element { private final ObservableValue output; private final int frequency; - public boolean startThisTimer = true; + private MyModelStateObserver observer; public Clock(ElementAttributes attributes) { output = new ObservableValue("C", 1); - frequency = attributes.get(AttributeKey.Frequency); + int f = attributes.get(AttributeKey.Frequency); + if (f < 1) f = 1; + frequency = f; } @Override @@ -40,42 +42,58 @@ public class Clock implements Element { } public void disableTimer() { - this.startThisTimer = false; + observer.remove(); } @Override public void registerNodes(Model model) { - model.addObserver(new ModelStateObserver() { - public Timer timer; + observer = new MyModelStateObserver(model, this, frequency, output); + model.addObserver(observer); + } - @Override - public void handleEvent(ModelEvent event) { - switch (event.getType()) { - case STARTED: - if (startThisTimer) { - int delay = 1000 / frequency; - if (delay < 100) delay = 100; - timer = new Timer(delay, e -> { - output.setValue(1 - output.getValue()); - try { - model.doStep(); - } catch (NodeException e1) { - SwingUtilities.invokeLater(new ErrorMessage("ClockError").addCause(e1)); - timer.stop(); - } - }); - timer.start(); - } - break; - case STOPPED: - if (timer != null) + private static class MyModelStateObserver implements ModelStateObserver { + private final Model model; + private final Clock clock; + private final int frequency; + private final ObservableValue output; + private Timer timer; + + public MyModelStateObserver(Model model, Clock clock, int frequency, ObservableValue output) { + this.model = model; + this.clock = clock; + this.frequency = frequency; + this.output = output; + } + + @Override + public void handleEvent(ModelEvent event) { + switch (event.getType()) { + case STARTED: + int delay = 1000 / frequency; + if (delay < 100) delay = 100; + timer = new Timer(delay, e -> { + output.setValue(1 - output.getValue()); + try { + model.doStep(); + } catch (NodeException e1) { + SwingUtilities.invokeLater(new ErrorMessage("ClockError").addCause(e1)); timer.stop(); - break; - case FETCHCLOCK: - event.registerClock(Clock.this); - break; - } + } + }); + timer.start(); + break; + case STOPPED: + if (timer != null) + timer.stop(); + break; + case FETCHCLOCK: + event.registerClock(clock); + break; } - }); + } + + public void remove() { + model.removeObserver(this); + } } } diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index ad0ddf0b7..0f3e6777c 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -41,6 +41,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { private static final Icon iconOpenWin = IconCreator.create("OpenNew24.gif"); private static final Icon iconSave = IconCreator.create("Save24.gif"); private static final Icon iconSaveAs = IconCreator.create("SaveAs24.gif"); + private static final Icon iconFast = IconCreator.create("FastForward24.gif"); private final CircuitComponent circuitComponent; private final ToolTipAction save; private final ElementLibrary library; @@ -227,6 +228,15 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { } }.setToolTip(Lang.get("menu_micro_tt")); + ToolTipAction runFast = new ToolTipAction(Lang.get("menu_fast"), iconFast) { + @Override + public void actionPerformed(ActionEvent e) { + createAndStartModel(false); + circuitComponent.setManualChangeObserver(new MicroStepObserver(model)); + } + }.setToolTip(Lang.get("menu_fast_tt")); + + ToolTipAction speedTest = new ToolTipAction(Lang.get("menu_speedTest")) { @Override public void actionPerformed(ActionEvent e) { @@ -250,6 +260,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { run.add(runModel.createJMenuItem()); run.add(runModelMicro.createJMenuItem()); run.add(doStep.createJMenuItem()); + run.add(runFast.createJMenuItem()); run.add(speedTest.createJMenuItem()); run.add(traceEnable); run.add(runClock); @@ -267,6 +278,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { toolBar.add(runModel.createJButtonNoText()); toolBar.add(runModelMicro.createJButtonNoText()); toolBar.add(doStep.createJButtonNoText()); + toolBar.add(runFast.createJButtonNoText()); toolBar.addSeparator(); diff --git a/src/main/resources/lang/lang_de.properties b/src/main/resources/lang/lang_de.properties index 747de2f3d..c0812f4e5 100644 --- a/src/main/resources/lang/lang_de.properties +++ b/src/main/resources/lang/lang_de.properties @@ -28,6 +28,8 @@ key_addrBits=Adress Bits key_flipSelPos=Tausche Position des Selectors key_rotation=Rotation key_width=Breite +key_cycles=Timeout Zyklen + rot_0=0\u00B0 rot_90=90\u00B0 rot_180=180\u00B0 @@ -113,6 +115,9 @@ menu_runClock_tt=Wenn gew\u00E4hlt, werden beim Starten auch die Taktgeber gesta menu_help=Hilfe menu_editAttributes=Model Attribute Bearbeiten menu_editAttributes_tt=Diese Attribute beeinflussen das Modell, wenn es in andere Modelle eingebettet wird. +menu_fast=Schneller Lauf +menu_fast_tt=F\u00FChrt das Modell aus, bis ein Stopsignal \u00FCber ein BRK-Element detektiert wird. + menu_about=\u00DCber Digital win_saveChanges=Ver\u00E4nderungen speichern? diff --git a/src/main/resources/lang/lang_en.properties b/src/main/resources/lang/lang_en.properties index b5d9e163d..257020619 100644 --- a/src/main/resources/lang/lang_en.properties +++ b/src/main/resources/lang/lang_en.properties @@ -28,6 +28,8 @@ key_addrBits=Address Bits key_flipSelPos=Flip selector position key_rotation=Rotation key_width=Width +key_cycles=Timeout cycles + rot_0=0\u00B0 rot_90=90\u00B0 rot_180=180\u00B0 @@ -112,7 +114,10 @@ menu_runClock_tt=If selected the clocks in the circuit are started menu_help=Help menu_about=About menu_editAttributes=Edit Models Attributes -menu_editAttributes_tt=These attributes effect the behavior is the model is included in othre models. +menu_editAttributes_tt=These attributes effect the behavior is the model is included in other models. +menu_fast=Run Fast +menu_fast_tt=Runs the model until a break is detected by the BRK element. + win_saveChanges=Save Changes? win_confirmExit=Confirm Exit!