import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
+import net.mograsim.logic.core.LogicObserver;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
private final List<ModelWire> wiresToForceInverted;
private final List<ModelWire> wiresToForceInvertedUnmodifiable;
+ private final Map<Consumer<Object>, LogicObserver> wireObsPerListener;
+
public WireForcingAtomicHighLevelStateHandler(SubmodelComponent component)
{
this(component, null);
this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce);
this.wiresToForceInverted = new ArrayList<>();
this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted);
+
+ this.wireObsPerListener = new HashMap<>();
+
if (params != null)
{
Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
wire.forceWireValues(vector);
}
+ @Override
+ public void addListener(Consumer<Object> stateChanged)
+ {
+ if (wireObsPerListener.containsKey(stateChanged))
+ return;
+ AtomicReference<Object> lastStateRef = new AtomicReference<>(getHighLevelState());
+ LogicObserver obs = w ->
+ {
+ Object newState = getHighLevelState();
+ if (!Objects.equals(lastStateRef.getAndSet(newState), newState))
+ stateChanged.accept(newState);
+ };
+ wireObsPerListener.put(stateChanged, obs);
+ for (ModelWire w : wiresToForce)
+ w.addObserver(obs);
+ for (ModelWire w : wiresToForceInverted)
+ w.addObserver(obs);
+ }
+
+ @Override
+ public void removeListener(Consumer<Object> stateChanged)
+ {
+ LogicObserver obs = wireObsPerListener.remove(stateChanged);
+ if (obs == null)
+ return;
+ for (ModelWire w : wiresToForce)
+ w.removeObserver(obs);
+ for (ModelWire w : wiresToForceInverted)
+ w.removeObserver(obs);
+ }
+
@Override
public String getIDForSerializing(IdentifyParams idParams)
{