This commit is contained in:
hneemann 2021-02-09 12:38:03 +01:00
parent 1fa909670b
commit 8a8f1260fc
6 changed files with 85 additions and 17 deletions

View File

@ -277,20 +277,27 @@ public class Model implements Iterable<Node>, SyncAccess {
synchronized private void stepWithCondition(boolean noise, StepCondition cond) {
try {
int counter = 0;
while (cond.doNextMicroStep() && state != State.CLOSED) {
if (counter++ > MAX_LOOP_COUNTER) {
if (oscillatingNodes == null)
oscillatingNodes = new HashSet<>();
if (counter > COLLECTING_LOOP_COUNTER) {
NodeException seemsToOscillate = new NodeException(Lang.get("err_seemsToOscillate")).addNodes(oscillatingNodes);
oscillatingNodes = null;
throw seemsToOscillate;
} else {
oscillatingNodes.addAll(nodesToUpdateNext);
if (cond.doNextMicroStep()) {
int counter = 0;
while (cond.doNextMicroStep() && state != State.CLOSED) {
if (counter++ > MAX_LOOP_COUNTER) {
if (oscillatingNodes == null)
oscillatingNodes = new HashSet<>();
if (counter > COLLECTING_LOOP_COUNTER) {
NodeException seemsToOscillate = new NodeException(Lang.get("err_seemsToOscillate")).addNodes(oscillatingNodes);
oscillatingNodes = null;
throw seemsToOscillate;
} else {
oscillatingNodes.addAll(nodesToUpdateNext);
}
}
doMicroStep(noise);
}
doMicroStep(noise);
} else {
// if a calculation is initiated but there is nothing to do because there was
// no gate input change, perform a burn check to detect short circuits caused by
// directly connected inputs.
fireEvent(ModelEvent.CHECKBURN);
}
} catch (Exception e) {
errorOccurred(e);
@ -473,7 +480,7 @@ public class Model implements Iterable<Node>, SyncAccess {
private void addObserverForEvent(ModelStateObserver observer, ModelEventType event) {
ArrayList<ModelStateObserver> obs = observers;
if (event == ModelEventType.STEP) {
if (event == ModelEventType.STEP || event == ModelEventType.CHECKBURN) {
if (observersStep == null)
observersStep = new ArrayList<>();
obs = observersStep;
@ -529,6 +536,7 @@ public class Model implements Iterable<Node>, SyncAccess {
for (ModelStateObserver observer : observersMicroStep)
observer.handleEvent(event);
break;
case CHECKBURN:
case STEP:
if (observersStep != null)
for (ModelStateObserver observer : observersStep)

View File

@ -27,6 +27,10 @@ public class ModelEvent {
* Shorthand for a ModelEventType.STEP event
*/
public static final ModelEvent STEP = new ModelEvent(ModelEventType.STEP);
/**
* Shorthand for a ModelEventType.CHECKBURN event
*/
public static final ModelEvent CHECKBURN = new ModelEvent(ModelEventType.CHECKBURN);
/**
* Shorthand for a ModelEventType.MICROSTEP event
*/

View File

@ -48,11 +48,17 @@ public enum ModelEventType {
EXTERNALCHANGE,
/**
* If fired if a micro step is calculated.
* Is fired if a micro step is calculated.
* This means the aktual nodes are calculated, but not the effected nodes.
*/
MICROSTEP,
/**
* Is fired in case a burn check needs to be done without the change of a gate.
* Can happen if inputs are connected directly.
*/
CHECKBURN,
/**
* Used to notify an error
*/

View File

@ -31,7 +31,7 @@ public final class BusModelStateObserver implements ModelStateObserverTyped {
@Override
public void handleEvent(ModelEvent event) {
if (event == ModelEvent.STEP && !busList.isEmpty()) {
if ((event == ModelEvent.STEP || event == ModelEvent.CHECKBURN) && !busList.isEmpty()) {
for (AbstractBusHandler bus : busList) {
bus.checkBurn();
}
@ -42,7 +42,7 @@ public final class BusModelStateObserver implements ModelStateObserverTyped {
@Override
public ModelEventType[] getEvents() {
return new ModelEventType[]{ModelEventType.STEP};
return new ModelEventType[]{ModelEventType.STEP, ModelEventType.CHECKBURN};
}
/**

View File

@ -51,7 +51,7 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(206, new FileScanner(this::check).scan(examples));
assertEquals(207, new FileScanner(this::check).scan(examples));
assertEquals(192, testCasesInFiles);
}

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>InDefault</string>
<value v="1" z="false"/>
</entry>
</elementAttributes>
<pos x="380" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="380" y="320"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="460" y="280"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="380" y="240"/>
<p2 x="420" y="240"/>
</wire>
<wire>
<p1 x="380" y="320"/>
<p2 x="420" y="320"/>
</wire>
<wire>
<p1 x="420" y="280"/>
<p2 x="460" y="280"/>
</wire>
<wire>
<p1 x="420" y="240"/>
<p2 x="420" y="280"/>
</wire>
<wire>
<p1 x="420" y="280"/>
<p2 x="420" y="320"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>