X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=plugins%2Fnet.mograsim.logic.model%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Fsnippets%2Fhighlevelstatehandlers%2Fstandard%2Fatomic%2FWireForcingAtomicHighLevelStateHandler.java;h=4f7cd4579e4078c68d1167f6c45dfcf01a14a02b;hb=69ec19d54ceb6d5abbb8b4faa55284af22174859;hp=276f5415c5302da08de79b5dc50e891afa56e700;hpb=7d05144c25daa53e60fc9ed9fd503546a86567f8;p=Mograsim.git diff --git a/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java b/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java index 276f5415..4f7cd457 100644 --- a/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java +++ b/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java @@ -2,11 +2,16 @@ package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic 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; @@ -24,6 +29,8 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt private final List wiresToForceInverted; private final List wiresToForceInvertedUnmodifiable; + private final Map, LogicObserver> wireObsPerListener; + public WireForcingAtomicHighLevelStateHandler(SubmodelComponent component) { this(component, null); @@ -36,6 +43,9 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce); this.wiresToForceInverted = new ArrayList<>(); this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted); + + this.wireObsPerListener = new HashMap<>(); + if (params != null) { Map wiresByName = component.submodel.getWiresByName(); @@ -99,14 +109,20 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt @Override public Object getHighLevelState() { - BitVector result = BitVector.of(Bit.ZERO, logicWidth); - for (ModelWire wire : wiresToForceInverted) - if (wire.hasCoreModelBinding()) - result = result.or(wire.getWireValues()); - result = result.not(); + BitVector result = BitVector.of(Bit.Z, logicWidth); + + if (!wiresToForceInverted.isEmpty()) + { + for (ModelWire wire : wiresToForceInverted) + if (wire.hasCoreModelBinding()) + result = result.join(wire.getWireValues()); + result = result.not(); + } + for (ModelWire wire : wiresToForce) if (wire.hasCoreModelBinding()) - result = result.and(wire.getWireValues()); + result = result.join(wire.getWireValues()); + return result; } @@ -127,6 +143,37 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt wire.forceWireValues(vector); } + @Override + public void addListener(Consumer stateChanged) + { + if (wireObsPerListener.containsKey(stateChanged)) + return; + AtomicReference 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 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) {