From e26c4f643df62e63f5eb11af1a3c5ea551462820 Mon Sep 17 00:00:00 2001 From: hneemann Date: Mon, 21 Mar 2016 20:13:32 +0100 Subject: [PATCH] added a speed test which runs the model without a gui connected to it. --- .../java/de/neemann/digital/core/Model.java | 14 +++-- .../de/neemann/digital/core/ModelEvent.java | 37 +++++++++++++ .../digital/core/ModelStateObserver.java | 4 +- .../de/neemann/digital/core/SpeedTest.java | 54 +++++++++++++++++++ .../de/neemann/digital/core/wiring/Clock.java | 42 ++++++++------- .../java/de/neemann/digital/gui/Main.java | 18 +++++++ 6 files changed, 144 insertions(+), 25 deletions(-) create mode 100644 src/main/java/de/neemann/digital/core/ModelEvent.java create mode 100644 src/main/java/de/neemann/digital/core/SpeedTest.java diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index 3c746b9b7..220a089ae 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -1,5 +1,7 @@ package de.neemann.digital.core; +import de.neemann.digital.core.wiring.Clock; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -59,12 +61,12 @@ public class Model { nodesToUpdateNext.addAll(nodes); isInitialized = true; doStep(noise); - fireEvent(ModelStateObserver.Event.STARTED); + fireEvent(new ModelEvent(ModelEvent.Event.STARTED)); } public void close() { stopped = true; - fireEvent(ModelStateObserver.Event.STOPPED); + fireEvent(new ModelEvent(ModelEvent.Event.STOPPED)); } public void addToUpdateList(Node node) { @@ -150,8 +152,14 @@ public class Model { observers.add(observer); } - private void fireEvent(ModelStateObserver.Event event) { + private void fireEvent(ModelEvent event) { for (ModelStateObserver observer : observers) observer.handleEvent(event); } + + public ArrayList getClocks() { + ModelEvent e = new ModelEvent(ModelEvent.Event.FETCHCLOCK); + fireEvent(e); + return e.getClocks(); + } } diff --git a/src/main/java/de/neemann/digital/core/ModelEvent.java b/src/main/java/de/neemann/digital/core/ModelEvent.java new file mode 100644 index 000000000..591b9f8c1 --- /dev/null +++ b/src/main/java/de/neemann/digital/core/ModelEvent.java @@ -0,0 +1,37 @@ +package de.neemann.digital.core; + +import de.neemann.digital.core.wiring.Clock; + +import java.util.ArrayList; + +/** + * @author hneemann + */ +public class ModelEvent { + + + public enum Event {STARTED, STOPPED, FETCHCLOCK} + + ; + + private final Event event; + private ArrayList clocks; + + public ModelEvent(Event event) { + this.event = event; + } + + public Event getType() { + return event; + } + + public void registerClock(Clock clock) { + if (clocks == null) + clocks = new ArrayList(); + clocks.add(clock); + } + + public ArrayList getClocks() { + return clocks; + } +} diff --git a/src/main/java/de/neemann/digital/core/ModelStateObserver.java b/src/main/java/de/neemann/digital/core/ModelStateObserver.java index f55c27231..746266141 100644 --- a/src/main/java/de/neemann/digital/core/ModelStateObserver.java +++ b/src/main/java/de/neemann/digital/core/ModelStateObserver.java @@ -5,8 +5,6 @@ package de.neemann.digital.core; */ public interface ModelStateObserver { - enum Event {STARTED, STOPPED} - - void handleEvent(Event event); + void handleEvent(ModelEvent event); } diff --git a/src/main/java/de/neemann/digital/core/SpeedTest.java b/src/main/java/de/neemann/digital/core/SpeedTest.java new file mode 100644 index 000000000..e15dd2356 --- /dev/null +++ b/src/main/java/de/neemann/digital/core/SpeedTest.java @@ -0,0 +1,54 @@ +package de.neemann.digital.core; + +import de.neemann.digital.core.wiring.Clock; + +import java.util.ArrayList; + +/** + * @author hneemann + */ +public class SpeedTest { + private static final int LOOPCOUNTER = 2000; + private final Model model; + + public SpeedTest(Model model) { + this.model = model; + } + + public double calculate() throws NodeException { + ArrayList clocks = model.getClocks(); + if (clocks.isEmpty()) + throw new NodeException("NoClockFound"); + else if (clocks.size() > 1) + throw new NodeException("MoreThenOneClocksFound"); + + + Clock clock = clocks.get(0); + model.init(true); + ObservableValue clockValue = clock.getOutputs()[0]; + int state = (int) clockValue.getValue(); + + long aktTime; + long starTime = System.currentTimeMillis(); + int loops = 0; + do { + for (int i = 0; i < LOOPCOUNTER; i++) { + state = 1 - state; + clockValue.setValue(state); + } + loops++; + aktTime = System.currentTimeMillis(); + } while (aktTime - starTime < 1000); + + long cycles = ((long) loops) * LOOPCOUNTER / 2; + double time = (aktTime - starTime) / 1000.0; + + double freqency = cycles / time; + + System.out.println("cycles: " + cycles); + System.out.println("time : " + time + "s"); + System.out.println("freq :" + freqency); + + return freqency; + } +} 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 7701b8d08..377e78e4b 100644 --- a/src/main/java/de/neemann/digital/core/wiring/Clock.java +++ b/src/main/java/de/neemann/digital/core/wiring/Clock.java @@ -1,9 +1,6 @@ package de.neemann.digital.core.wiring; -import de.neemann.digital.core.Model; -import de.neemann.digital.core.ModelStateObserver; -import de.neemann.digital.core.NodeException; -import de.neemann.digital.core.ObservableValue; +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.ElementAttributes; @@ -42,28 +39,35 @@ public class Clock implements Element { @Override public void registerNodes(Model model) { model.addObserver(new ModelStateObserver() { + public boolean startThisTimer = true; public Timer timer; @Override - public void handleEvent(Event event) { - switch (event) { + 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(); - } - }); - timer.start(); + 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: - timer.stop(); + if (timer != null) + timer.stop(); break; + case FETCHCLOCK: + event.registerClock(Clock.this); + startThisTimer = false; } } }); diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index c332e8e9b..53b4f8cb7 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -6,6 +6,7 @@ import com.thoughtworks.xstream.io.xml.StaxDriver; import de.neemann.digital.core.Model; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.Observer; +import de.neemann.digital.core.SpeedTest; import de.neemann.digital.core.element.AttributeKey; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.gui.components.CircuitComponent; @@ -164,9 +165,26 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave { } }.setToolTip("Runs the Model in Micro Stepping Mode"); + ToolTipAction speedTest = new ToolTipAction("SpeedTest") { + @Override + public void actionPerformed(ActionEvent e) { + try { + modelDescription = new ModelDescription(circuitComponent.getCircuit(), library); + model = modelDescription.createModel(); + SpeedTest speedTest = new SpeedTest(model); + double frequency = speedTest.calculate(); + JOptionPane.showMessageDialog(Main.this, "Frequency: " + frequency); + } catch (Exception e1) { + new ErrorMessage("SpeedTestError").addCause(e1).show(); + } + } + }.setToolTip("Runs the Model"); + + run.add(runModel.createJMenuItem()); run.add(runModelMicro.createJMenuItem()); run.add(doStep.createJMenuItem()); + run.add(speedTest.createJMenuItem()); doStep.setEnabled(false); JToolBar toolBar = new JToolBar();