mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 17:04:42 -04:00
fixes an issue with seven segment flicker suppression; closes #829
This commit is contained in:
parent
1335372602
commit
4bce1db132
@ -583,6 +583,26 @@ public class Model implements Iterable<Node>, SyncAccess {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an observer of the given class.
|
||||
* If no observer is available the factory is used to create and register one.
|
||||
*
|
||||
* @param observerClass the observers class
|
||||
* @param factory the factory to create an instance if necessary
|
||||
* @param <T> the type of the observer
|
||||
* @return the already present or newly created observer; never null
|
||||
*/
|
||||
public synchronized <T extends ModelStateObserverTyped> T getOrCreateObserver(Class<T> observerClass, ObserverFactory<T> factory) {
|
||||
T o = getObserver(observerClass);
|
||||
if (o == null) {
|
||||
o = factory.create();
|
||||
if (o == null)
|
||||
throw new NullPointerException("no observer created!");
|
||||
addObserver(o);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
private void fireEvent(ModelEvent event) {
|
||||
switch (event.getType()) {
|
||||
case MICROSTEP:
|
||||
@ -1083,4 +1103,16 @@ public class Model implements Iterable<Node>, SyncAccess {
|
||||
private interface StepCondition {
|
||||
boolean doNextMicroStep() throws NodeException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory used to create a {@link ModelStateObserverTyped}
|
||||
*
|
||||
* @param <T> the type of the observer
|
||||
*/
|
||||
public interface ObserverFactory<T extends ModelStateObserverTyped> {
|
||||
/**
|
||||
* @return the created observer
|
||||
*/
|
||||
T create();
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +80,7 @@ public class DataBus {
|
||||
}
|
||||
}
|
||||
|
||||
BusModelStateObserver obs = model.getObserver(BusModelStateObserver.class);
|
||||
if (obs == null) {
|
||||
obs = new BusModelStateObserver();
|
||||
model.addObserver(obs);
|
||||
}
|
||||
BusModelStateObserver obs = model.getOrCreateObserver(BusModelStateObserver.class, BusModelStateObserver::new);
|
||||
|
||||
commonBusValue = new CommonBusValue(bits, obs, resistor, outputs, net == null ? null : net.getOrigin());
|
||||
for (ObservableValue p : outputs)
|
||||
|
@ -5,9 +5,7 @@
|
||||
*/
|
||||
package de.neemann.digital.draw.shapes;
|
||||
|
||||
import de.neemann.digital.core.ObservableValue;
|
||||
import de.neemann.digital.core.ObservableValues;
|
||||
import de.neemann.digital.core.Observer;
|
||||
import de.neemann.digital.core.*;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.core.element.PinDescriptions;
|
||||
@ -18,6 +16,10 @@ import de.neemann.digital.draw.elements.Pins;
|
||||
import de.neemann.digital.draw.graphics.Graphic;
|
||||
import de.neemann.digital.draw.graphics.Style;
|
||||
import de.neemann.digital.draw.graphics.Vector;
|
||||
import de.neemann.digital.draw.model.ModelCreator;
|
||||
import de.neemann.digital.draw.model.ModelEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE;
|
||||
import static de.neemann.digital.draw.shapes.GenericShape.SIZE2;
|
||||
@ -33,6 +35,7 @@ public class SevenSegShape extends SevenShape {
|
||||
private LEDState[] ledStates;
|
||||
private final boolean[] displayStates;
|
||||
private Pins pins;
|
||||
private SegmentUpdater segmentUpdater;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@ -76,11 +79,17 @@ public class SevenSegShape extends SevenShape {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerModel(ModelCreator modelCreator, Model model, ModelEntry element) {
|
||||
if (commonConnection && persistence)
|
||||
segmentUpdater = model.getOrCreateObserver(SegmentUpdater.class, SegmentUpdater::new);
|
||||
}
|
||||
|
||||
private LEDState createLEDState(int i, ObservableValues inputs) {
|
||||
if (commonConnection) {
|
||||
if (persistence)
|
||||
return new CommonConnectionPersist(inputs.get(i), inputs.get(8));
|
||||
else
|
||||
if (persistence) {
|
||||
return new CommonConnectionPersist(inputs.get(i), inputs.get(8), segmentUpdater);
|
||||
} else
|
||||
return new CommonConnection(inputs.get(i), inputs.get(8));
|
||||
} else {
|
||||
ObservableValue in = inputs.get(i);
|
||||
@ -141,24 +150,46 @@ public class SevenSegShape extends SevenShape {
|
||||
}
|
||||
//CHECKSTYLE.ON: FinalClass
|
||||
|
||||
private final class CommonConnectionPersist extends CommonConnection implements Observer {
|
||||
private final class CommonConnectionPersist extends CommonConnection {
|
||||
private boolean led;
|
||||
|
||||
private CommonConnectionPersist(ObservableValue led, ObservableValue cc) {
|
||||
private CommonConnectionPersist(ObservableValue led, ObservableValue cc, SegmentUpdater segmentUpdater) {
|
||||
super(led, cc);
|
||||
led.addObserver(this);
|
||||
cc.addObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasChanged() {
|
||||
if (!isHighZ())
|
||||
led = isOn();
|
||||
segmentUpdater.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getState() {
|
||||
return led;
|
||||
}
|
||||
|
||||
public void updateState() {
|
||||
if (!isHighZ())
|
||||
led = isOn();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SegmentUpdater implements ModelStateObserverTyped {
|
||||
private final ArrayList<CommonConnectionPersist> segments;
|
||||
|
||||
private SegmentUpdater() {
|
||||
segments = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(ModelEvent event) {
|
||||
if (event.getType() == ModelEventType.STEP)
|
||||
for (CommonConnectionPersist c : segments)
|
||||
c.updateState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelEventType[] getEvents() {
|
||||
return new ModelEventType[]{ModelEventType.STEP};
|
||||
}
|
||||
|
||||
public void add(CommonConnectionPersist commonConnectionPersist) {
|
||||
segments.add(commonConnectionPersist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user