removed ModelBuilder

This commit is contained in:
hneemann 2016-03-29 16:43:07 +02:00
parent 1a4087dc0a
commit c5c071f223
9 changed files with 104 additions and 202 deletions

View File

@ -1,5 +1,6 @@
package de.neemann.digital.core; package de.neemann.digital.core;
import de.neemann.digital.core.wiring.Break;
import de.neemann.digital.core.wiring.Clock; import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
@ -18,6 +19,10 @@ import java.util.List;
*/ */
public class Model { public class Model {
private final ArrayList<Clock> clocks;
private final ArrayList<Break> breaks;
private final ArrayList<ObservableValue> signals;
private final ArrayList<Node> nodes; private final ArrayList<Node> nodes;
private final ArrayList<ModelStateObserver> observers; private final ArrayList<ModelStateObserver> observers;
private ArrayList<Node> nodesToUpdateAct; private ArrayList<Node> nodesToUpdateAct;
@ -25,13 +30,15 @@ public class Model {
private int version; private int version;
private int maxCounter = 1000; private int maxCounter = 1000;
private boolean isInitialized = false; private boolean isInitialized = false;
private boolean stopped = false;
public Model() { public Model() {
this.clocks = new ArrayList<>();
this.breaks = new ArrayList<>();
this.signals = new ArrayList<>();
this.nodes = new ArrayList<>(); this.nodes = new ArrayList<>();
this.nodesToUpdateAct = new ArrayList<>(); this.nodesToUpdateAct = new ArrayList<>();
this.nodesToUpdateNext = new ArrayList<>(); this.nodesToUpdateNext = new ArrayList<>();
observers = new ArrayList<>(); this.observers = new ArrayList<>();
} }
public int getStepCounter() { public int getStepCounter() {
@ -68,12 +75,11 @@ public class Model {
nodesToUpdateNext.addAll(nodes); nodesToUpdateNext.addAll(nodes);
isInitialized = true; isInitialized = true;
doStep(noise); doStep(noise);
fireEvent(new ModelEvent(ModelEvent.Event.STARTED)); fireEvent(ModelEvent.STARTED);
} }
public void close() { public void close() {
stopped = true; fireEvent(ModelEvent.STOPPED);
fireEvent(new ModelEvent(ModelEvent.Event.STOPPED));
} }
public void addToUpdateList(Node node) { public void addToUpdateList(Node node) {
@ -167,12 +173,22 @@ public class Model {
} }
public ArrayList<Clock> getClocks() { public ArrayList<Clock> getClocks() {
ModelEvent e = new ModelEvent(ModelEvent.Event.FETCHCLOCK); return clocks;
fireEvent(e);
return e.getClocks();
} }
public List<Node> getNodes() { public List<Node> getNodes() {
return Collections.unmodifiableList(nodes); return Collections.unmodifiableList(nodes);
} }
public void addClock(Clock clock) {
clocks.add(clock);
}
public void addBreak(Break aBreak) {
breaks.add(aBreak);
}
public void addSignal(ObservableValue value) {
signals.add(value);
}
} }

View File

@ -1,25 +1,19 @@
package de.neemann.digital.core; package de.neemann.digital.core;
import de.neemann.digital.core.wiring.Break;
import de.neemann.digital.core.wiring.Clock;
import java.util.ArrayList;
/** /**
* @author hneemann * @author hneemann
*/ */
public class ModelEvent { public class ModelEvent {
public static final ModelEvent STEP = new ModelEvent(Event.STEP); public static final ModelEvent STEP = new ModelEvent(Event.STEP);
public static final ModelEvent STARTED = new ModelEvent(Event.STARTED);
public static final ModelEvent STOPPED = new ModelEvent(Event.STOPPED);
public enum Event {STARTED, STOPPED, FETCHCLOCK, FETCHBREAK, STEP} public enum Event {STARTED, STOPPED, STEP}
private final Event event; private final Event event;
private ArrayList<Clock> clocks;
private ArrayList<Break> breaks;
public ModelEvent(Event event) { private ModelEvent(Event event) {
this.event = event; this.event = event;
} }
@ -27,23 +21,4 @@ public class ModelEvent {
return event; return event;
} }
public void registerClock(Clock clock) {
if (clocks == null)
clocks = new ArrayList<Clock>();
clocks.add(clock);
}
public ArrayList<Clock> getClocks() {
return clocks;
}
public void registerBreak(Break aBreak) {
if (breaks == null)
breaks = new ArrayList<Break>();
breaks.add(aBreak);
}
public ArrayList<Break> getBreaks() {
return breaks;
}
} }

View File

@ -25,7 +25,6 @@ public class SpeedTest {
Clock clock = clocks.get(0); Clock clock = clocks.get(0);
clock.disableTimer();
model.init(); model.init();
ObservableValue clockValue = clock.getOutputs()[0]; ObservableValue clockValue = clock.getOutputs()[0];
int state = (int) clockValue.getValue(); int state = (int) clockValue.getValue();

View File

@ -1,6 +1,8 @@
package de.neemann.digital.core.wiring; package de.neemann.digital.core.wiring;
import de.neemann.digital.core.*; 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.AttributeKey;
import de.neemann.digital.core.element.Element; import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementTypeDescription; import de.neemann.digital.core.element.ElementTypeDescription;
@ -23,7 +25,7 @@ public class Break implements Element {
input = inputs[0].checkBits(1, null); input = inputs[0].checkBits(1, null);
} }
public ObservableValue getInput() { public ObservableValue getBreakInput() {
return input; return input;
} }
@ -34,28 +36,7 @@ public class Break implements Element {
@Override @Override
public void registerNodes(Model model) { public void registerNodes(Model model) {
model.addObserver(new MyModelStateObserver(model, this)); model.addBreak(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;
}
}
}
} }

View File

@ -1,14 +1,13 @@
package de.neemann.digital.core.wiring; package de.neemann.digital.core.wiring;
import de.neemann.digital.core.*; 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.AttributeKey;
import de.neemann.digital.core.element.Element; import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription; import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import de.neemann.gui.ErrorMessage;
import javax.swing.*;
/** /**
* @author hneemann * @author hneemann
@ -22,7 +21,6 @@ public class Clock implements Element {
private final ObservableValue output; private final ObservableValue output;
private final int frequency; private final int frequency;
private MyModelStateObserver observer;
public Clock(ElementAttributes attributes) { public Clock(ElementAttributes attributes) {
output = new ObservableValue("C", 1); output = new ObservableValue("C", 1);
@ -41,59 +39,62 @@ public class Clock implements Element {
return new ObservableValue[]{output}; return new ObservableValue[]{output};
} }
public void disableTimer() {
observer.remove();
}
@Override @Override
public void registerNodes(Model model) { public void registerNodes(Model model) {
observer = new MyModelStateObserver(model, this, frequency, output); model.addClock(this);
model.addObserver(observer);
} }
private static class MyModelStateObserver implements ModelStateObserver { public ObservableValue getClockOutput() {
private final Model model; return output;
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 int getFrequency() {
public void handleEvent(ModelEvent event) { return frequency;
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();
break;
case STOPPED:
if (timer != null)
timer.stop();
break;
case FETCHCLOCK:
event.registerClock(clock);
break;
}
} }
public void remove() { // private static class MyModelStateObserver implements ModelStateObserver {
model.removeObserver(this); // 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();
// }
// });
// timer.start();
// break;
// case STOPPED:
// if (timer != null)
// timer.stop();
// break;
// case FETCHCLOCK:
// event.registerClock(clock);
// break;
// }
// }
//
// public void remove() {
// model.removeObserver(this);
// }
// }
} }

View File

@ -1,59 +0,0 @@
package de.neemann.digital.draw.model;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.gui.Main;
import java.util.ArrayList;
/**
* @author hneemann
*/
public class ModelBuilder {
private final Circuit circuit;
private boolean disableClock = false;
private boolean enableTrace = false;
private ModelDescription modelDescription;
public ModelBuilder(Circuit circuit) {
this.circuit = circuit;
}
public ModelBuilder setDisableClock(boolean disableClock) {
this.disableClock = disableClock;
return this;
}
public ModelBuilder setEnableTrace(boolean enableTrace, Main main) {
this.enableTrace = enableTrace;
return this;
}
public Model build(ElementLibrary library) throws PinException, NodeException {
modelDescription = new ModelDescription(circuit, library);
Model model = modelDescription.createModel();
System.out.println("build " + model.getNodes().size() + " Nodes");
if (enableTrace) {
}
if (disableClock) {
ArrayList<Clock> clocks = model.getClocks();
if (clocks != null)
for (Clock c : clocks)
c.disableTimer();
}
return model;
}
public ModelDescription getModelDescription() {
return modelDescription;
}
}

View File

@ -8,7 +8,6 @@ import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException; import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.PinOrder; import de.neemann.digital.draw.elements.PinOrder;
import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.model.ModelBuilder;
import de.neemann.digital.draw.model.ModelDescription; import de.neemann.digital.draw.model.ModelDescription;
import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.components.CircuitComponent; import de.neemann.digital.gui.components.CircuitComponent;
@ -241,11 +240,11 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
Model model = new ModelBuilder(circuitComponent.getCircuit()) Model model = new ModelDescription(circuitComponent.getCircuit(), library).createModel();
.build(library);
SpeedTest speedTest = new SpeedTest(model); SpeedTest speedTest = new SpeedTest(model);
double frequency = speedTest.calculate(); double frequency = speedTest.calculate();
circuitComponent.getCircuit().clearState();
JOptionPane.showMessageDialog(Main.this, "Frequency: " + frequency); JOptionPane.showMessageDialog(Main.this, "Frequency: " + frequency);
} catch (Exception e1) { } catch (Exception e1) {
new ErrorMessage("SpeedTestError").addCause(e1).show(); new ErrorMessage("SpeedTestError").addCause(e1).show();
@ -300,38 +299,30 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
} }
private void createAndStartModel(boolean runClock) { private void createAndStartModel(boolean runClock) {
ModelBuilder mb = null;
try { try {
if (modelDescription != null) if (modelDescription != null)
modelDescription.highLightOff(); modelDescription.highLightOff();
circuitComponent.setModeAndReset(CircuitComponent.Mode.running); circuitComponent.setModeAndReset(CircuitComponent.Mode.running);
mb = new ModelBuilder(circuitComponent.getCircuit()) modelDescription = new ModelDescription(circuitComponent.getCircuit(), library);
.setDisableClock(!runClock)
.setEnableTrace(traceEnable.isSelected(), Main.this);
model = mb.build(library);
modelDescription = mb.getModelDescription();
modelDescription.connectToGui(circuitComponent); modelDescription.connectToGui(circuitComponent);
model.init(); model.init();
} catch (NodeException e) { } catch (NodeException e) {
if (mb.getModelDescription() != null) { if (modelDescription != null) {
modelDescription = mb.getModelDescription();
if (e.getNodes() != null) if (e.getNodes() != null)
mb.getModelDescription().highLight(e.getNodes()); modelDescription.highLight(e.getNodes());
else else
mb.getModelDescription().highLight(e.getValues()); modelDescription.highLight(e.getValues());
circuitComponent.repaint(); circuitComponent.repaint();
} }
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorCreatingModel")).addCause(e).setComponent(Main.this)); SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorCreatingModel")).addCause(e).setComponent(Main.this));
circuitComponent.setModeAndReset(CircuitComponent.Mode.part); circuitComponent.setModeAndReset(CircuitComponent.Mode.part);
} catch (PinException e) { } catch (PinException e) {
if (mb.getModelDescription() != null) { if (modelDescription != null) {
modelDescription = mb.getModelDescription(); modelDescription.highLight(e.getVisualElement());
mb.getModelDescription().highLight(e.getVisualElement());
if (e.getNet() != null) if (e.getNet() != null)
e.getNet().setHighLight(true); e.getNet().setHighLight(true);
circuitComponent.repaint(); circuitComponent.repaint();

View File

@ -7,7 +7,6 @@ import de.neemann.digital.core.element.Element;
import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException; import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.model.ModelBuilder;
import de.neemann.digital.draw.model.ModelDescription; import de.neemann.digital.draw.model.ModelDescription;
import de.neemann.digital.draw.model.ModelEntry; import de.neemann.digital.draw.model.ModelEntry;
import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.draw.shapes.ShapeFactory;
@ -37,10 +36,9 @@ public class TestExecuter {
File filename = new File(Resources.getRoot(), name); File filename = new File(Resources.getRoot(), name);
Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(library)); Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(library));
ModelBuilder mb = new ModelBuilder(circuit); ModelDescription mb = new ModelDescription(circuit, library);
Model model = mb.build(library);
return new TestExecuter(model, true).setUp(mb.getModelDescription()); return new TestExecuter(mb.createModel(), true).setUp(mb);
} }

View File

@ -5,7 +5,7 @@ import de.neemann.digital.core.Model;
import de.neemann.digital.core.Node; import de.neemann.digital.core.Node;
import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.library.ElementLibrary; import de.neemann.digital.draw.library.ElementLibrary;
import de.neemann.digital.draw.model.ModelBuilder; import de.neemann.digital.draw.model.ModelDescription;
import de.neemann.digital.draw.model.ModelEntry; import de.neemann.digital.draw.model.ModelEntry;
import de.neemann.digital.draw.shapes.ShapeFactory; import de.neemann.digital.draw.shapes.ShapeFactory;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -30,16 +30,16 @@ public class TestAnd extends TestCase {
File filename = new File(Resources.getRoot(), "dig/and.dig"); File filename = new File(Resources.getRoot(), "dig/and.dig");
Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(new ElementLibrary())); Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(new ElementLibrary()));
ModelBuilder mb = new ModelBuilder(circuit); ModelDescription md = new ModelDescription(circuit, library);
Model model = mb.build(library); Model model = md.createModel();
List<Node> nodes = model.getNodes(); List<Node> nodes = model.getNodes();
assertEquals(1, nodes.size()); assertEquals(1, nodes.size());
// get inputs and outputs // get inputs and outputs
List<ModelEntry> inputs = mb.getModelDescription().getEntries("In"); List<ModelEntry> inputs = md.getEntries("In");
assertEquals(2, inputs.size()); assertEquals(2, inputs.size());
List<ModelEntry> outputs = mb.getModelDescription().getEntries("Out"); List<ModelEntry> outputs = md.getEntries("Out");
assertEquals(1, outputs.size()); assertEquals(1, outputs.size());
// check the inputs state: the input itself has an output // check the inputs state: the input itself has an output