mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -04:00
removed ModelBuilder
This commit is contained in:
parent
1a4087dc0a
commit
c5c071f223
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
public ObservableValue getClockOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public int getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user