package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
-import net.mograsim.logic.model.model.wires.GUIWire;
+import net.mograsim.logic.model.model.wires.ModelWire;
import net.mograsim.logic.model.serializing.IdentifyParams;
import net.mograsim.logic.model.snippets.SnippetDefinintion;
import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
{
- private SubmodelComponent component;
+ private final SubmodelComponent component;
private int logicWidth;
- private final List<GUIWire> wiresToForce;
- private final List<GUIWire> wiresToForceInverted;
+ private final List<ModelWire> wiresToForce;
+ private final List<ModelWire> wiresToForceUnmodifiable;
+ private final List<ModelWire> wiresToForceInverted;
+ private final List<ModelWire> wiresToForceInvertedUnmodifiable;
public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
{
{
this.component = context.component;
this.wiresToForce = new ArrayList<>();
+ this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce);
this.wiresToForceInverted = new ArrayList<>();
+ this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted);
if (params != null)
{
- Map<String, GUIWire> wiresByName = component.submodel.getWiresByName();
- setWiresToForce(params.wiresToForce.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()),
- params.wiresToForceInverted.stream().map((Function<String, GUIWire>) wiresByName::get).collect(Collectors.toList()));
+ Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
+ setWiresToForce(params.wiresToForce.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()),
+ params.wiresToForceInverted.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()));
}
+ component.submodel.addWireRemovedListener(w ->
+ {
+ wiresToForce.removeIf(w::equals);
+ wiresToForceInverted.removeIf(w::equals);
+ });
}
- public void set(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
+ public void set(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
{
setWiresToForce(wiresToForce, wiresToForceInverted);
}
- public void setWiresToForce(List<GUIWire> wiresToForce, List<GUIWire> wiresToForceInverted)
+ public void setWiresToForce(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
{
clearWiresToForce();
- for (GUIWire wire : wiresToForce)
+ for (ModelWire wire : wiresToForce)
addWireToForce(wire, false);
- for (GUIWire wire : wiresToForceInverted)
+ for (ModelWire wire : wiresToForceInverted)
addWireToForce(wire, true);
}
- public void addWireToForce(GUIWire wire, boolean inverted)
+ public void addWireToForce(ModelWire wire, boolean inverted)
{
if (component.submodel.getWiresByName().get(wire.name) != wire)
throw new IllegalArgumentException("Can only force wires belonging to the parent component of this handler");
logicWidth = wire.logicWidth;
else if (wire.logicWidth != logicWidth)
throw new IllegalArgumentException("Can only force wires of the same logic width");
+ // this can add the same wire multiple times, but maybe there is a weird configuration where it is neccessary, due to race
+ // conditions, to force the same wire twice.
if (inverted)
wiresToForceInverted.add(wire);
else
logicWidth = 0;
}
+ public List<ModelWire> getWiresToForce()
+ {
+ return wiresToForceUnmodifiable;
+ }
+
+ public List<ModelWire> getWiresToForceInverted()
+ {
+ return wiresToForceInvertedUnmodifiable;
+ }
+
@Override
public Object getHighLevelState()
{
BitVector result = BitVector.of(Bit.ZERO, logicWidth);
- for (GUIWire wire : wiresToForceInverted)
- if (wire.hasLogicModelBinding())
+ for (ModelWire wire : wiresToForceInverted)
+ if (wire.hasCoreModelBinding())
result = result.or(wire.getWireValues());
result = result.not();
- for (GUIWire wire : wiresToForce)
- if (wire.hasLogicModelBinding())
+ for (ModelWire wire : wiresToForce)
+ if (wire.hasCoreModelBinding())
result = result.and(wire.getWireValues());
return result;
}
vector = BitVector.of((Bit) newState);
else
vector = (BitVector) newState;
- for (GUIWire wire : wiresToForce)
- if (wire.hasLogicModelBinding())
+ for (ModelWire wire : wiresToForce)
+ if (wire.hasCoreModelBinding())
wire.forceWireValues(vector);
vector = vector.not();
- for (GUIWire wire : wiresToForceInverted)
- if (wire.hasLogicModelBinding())
+ for (ModelWire wire : wiresToForceInverted)
+ if (wire.hasCoreModelBinding())
wire.forceWireValues(vector);
}