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;
import de.neemann.digital.core.wiring.Break;
import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.lang.Lang;
@ -18,6 +19,10 @@ import java.util.List;
*/
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<ModelStateObserver> observers;
private ArrayList<Node> nodesToUpdateAct;
@ -25,13 +30,15 @@ public class Model {
private int version;
private int maxCounter = 1000;
private boolean isInitialized = false;
private boolean stopped = false;
public Model() {
this.clocks = new ArrayList<>();
this.breaks = new ArrayList<>();
this.signals = new ArrayList<>();
this.nodes = new ArrayList<>();
this.nodesToUpdateAct = new ArrayList<>();
this.nodesToUpdateNext = new ArrayList<>();
observers = new ArrayList<>();
this.observers = new ArrayList<>();
}
public int getStepCounter() {
@ -68,12 +75,11 @@ public class Model {
nodesToUpdateNext.addAll(nodes);
isInitialized = true;
doStep(noise);
fireEvent(new ModelEvent(ModelEvent.Event.STARTED));
fireEvent(ModelEvent.STARTED);
}
public void close() {
stopped = true;
fireEvent(new ModelEvent(ModelEvent.Event.STOPPED));
fireEvent(ModelEvent.STOPPED);
}
public void addToUpdateList(Node node) {
@ -167,12 +173,22 @@ public class Model {
}
public ArrayList<Clock> getClocks() {
ModelEvent e = new ModelEvent(ModelEvent.Event.FETCHCLOCK);
fireEvent(e);
return e.getClocks();
return clocks;
}
public List<Node> getNodes() {
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;
import de.neemann.digital.core.wiring.Break;
import de.neemann.digital.core.wiring.Clock;
import java.util.ArrayList;
/**
* @author hneemann
*/
public class ModelEvent {
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 ArrayList<Clock> clocks;
private ArrayList<Break> breaks;
public ModelEvent(Event event) {
private ModelEvent(Event event) {
this.event = event;
}
@ -27,23 +21,4 @@ public class ModelEvent {
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.disableTimer();
model.init();
ObservableValue clockValue = clock.getOutputs()[0];
int state = (int) clockValue.getValue();

View File

@ -1,6 +1,8 @@
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.Element;
import de.neemann.digital.core.element.ElementTypeDescription;
@ -23,7 +25,7 @@ public class Break implements Element {
input = inputs[0].checkBits(1, null);
}
public ObservableValue getInput() {
public ObservableValue getBreakInput() {
return input;
}
@ -34,28 +36,7 @@ public class Break implements Element {
@Override
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;
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.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.lang.Lang;
import de.neemann.gui.ErrorMessage;
import javax.swing.*;
/**
* @author hneemann
@ -22,7 +21,6 @@ public class Clock implements Element {
private final ObservableValue output;
private final int frequency;
private MyModelStateObserver observer;
public Clock(ElementAttributes attributes) {
output = new ObservableValue("C", 1);
@ -41,59 +39,62 @@ public class Clock implements Element {
return new ObservableValue[]{output};
}
public void disableTimer() {
observer.remove();
}
@Override
public void registerNodes(Model model) {
observer = new MyModelStateObserver(model, this, frequency, output);
model.addObserver(observer);
model.addClock(this);
}
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;
public ObservableValue getClockOutput() {
return 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 int getFrequency() {
return frequency;
}
public void remove() {
model.removeObserver(this);
}
}
// 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();
// }
// });
// 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.PinOrder;
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.shapes.ShapeFactory;
import de.neemann.digital.gui.components.CircuitComponent;
@ -241,11 +240,11 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
@Override
public void actionPerformed(ActionEvent e) {
try {
Model model = new ModelBuilder(circuitComponent.getCircuit())
.build(library);
Model model = new ModelDescription(circuitComponent.getCircuit(), library).createModel();
SpeedTest speedTest = new SpeedTest(model);
double frequency = speedTest.calculate();
circuitComponent.getCircuit().clearState();
JOptionPane.showMessageDialog(Main.this, "Frequency: " + frequency);
} catch (Exception e1) {
new ErrorMessage("SpeedTestError").addCause(e1).show();
@ -300,38 +299,30 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
}
private void createAndStartModel(boolean runClock) {
ModelBuilder mb = null;
try {
if (modelDescription != null)
modelDescription.highLightOff();
circuitComponent.setModeAndReset(CircuitComponent.Mode.running);
mb = new ModelBuilder(circuitComponent.getCircuit())
.setDisableClock(!runClock)
.setEnableTrace(traceEnable.isSelected(), Main.this);
model = mb.build(library);
modelDescription = mb.getModelDescription();
modelDescription = new ModelDescription(circuitComponent.getCircuit(), library);
modelDescription.connectToGui(circuitComponent);
model.init();
} catch (NodeException e) {
if (mb.getModelDescription() != null) {
modelDescription = mb.getModelDescription();
if (modelDescription != null) {
if (e.getNodes() != null)
mb.getModelDescription().highLight(e.getNodes());
modelDescription.highLight(e.getNodes());
else
mb.getModelDescription().highLight(e.getValues());
modelDescription.highLight(e.getValues());
circuitComponent.repaint();
}
SwingUtilities.invokeLater(new ErrorMessage(Lang.get("msg_errorCreatingModel")).addCause(e).setComponent(Main.this));
circuitComponent.setModeAndReset(CircuitComponent.Mode.part);
} catch (PinException e) {
if (mb.getModelDescription() != null) {
modelDescription = mb.getModelDescription();
mb.getModelDescription().highLight(e.getVisualElement());
if (modelDescription != null) {
modelDescription.highLight(e.getVisualElement());
if (e.getNet() != null)
e.getNet().setHighLight(true);
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.PinException;
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.shapes.ShapeFactory;
@ -37,10 +36,9 @@ public class TestExecuter {
File filename = new File(Resources.getRoot(), name);
Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(library));
ModelBuilder mb = new ModelBuilder(circuit);
Model model = mb.build(library);
ModelDescription mb = new ModelDescription(circuit, 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.draw.elements.Circuit;
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.shapes.ShapeFactory;
import junit.framework.TestCase;
@ -30,16 +30,16 @@ public class TestAnd extends TestCase {
File filename = new File(Resources.getRoot(), "dig/and.dig");
Circuit circuit = Circuit.loadCircuit(filename, new ShapeFactory(new ElementLibrary()));
ModelBuilder mb = new ModelBuilder(circuit);
Model model = mb.build(library);
ModelDescription md = new ModelDescription(circuit, library);
Model model = md.createModel();
List<Node> nodes = model.getNodes();
assertEquals(1, nodes.size());
// get inputs and outputs
List<ModelEntry> inputs = mb.getModelDescription().getEntries("In");
List<ModelEntry> inputs = md.getEntries("In");
assertEquals(2, inputs.size());
List<ModelEntry> outputs = mb.getModelDescription().getEntries("Out");
List<ModelEntry> outputs = md.getEntries("Out");
assertEquals(1, outputs.size());
// check the inputs state: the input itself has an output