package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
{
private final SubmodelComponent component;
private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlers;
+ private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlersUnmodifiable;
private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlers;
+ private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlersUnmodifiable;
public StandardHighLevelStateHandler(SubmodelComponent component)
{
{
this.component = component;
this.subcomponentHighLevelStateHandlers = new HashMap<>();
+ this.subcomponentHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(subcomponentHighLevelStateHandlers);
this.atomicHighLevelStateHandlers = new HashMap<>();
+ this.atomicHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(atomicHighLevelStateHandlers);
if (params != null)
{
params.subcomponentHighLevelStates.forEach(this::addSubcomponentHighLevelState);
subcomponentHighLevelStateHandlers.put(subcomponentStateID, handler);
}
+ public void removeSubcomponentHighLevelState(String subcomponentStateID)
+ {
+ checkHighLevelStateIDPart(subcomponentStateID);
+ subcomponentHighLevelStateHandlers.remove(subcomponentStateID);
+ }
+
+ public Map<String, SubcomponentHighLevelStateHandler> getSubcomponentHighLevelStates()
+ {
+ return subcomponentHighLevelStateHandlersUnmodifiable;
+ }
+
public AtomicHighLevelStateHandler addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandlerParams handlerParams)
{
return addAtomicHighLevelState(atomicStateID,
atomicHighLevelStateHandlers.put(atomicStateID, handler);
}
+ public void removeAtomicHighLevelState(String atomicStateID)
+ {
+ checkHighLevelStateIDPart(atomicStateID);
+ atomicHighLevelStateHandlers.remove(atomicStateID);
+ }
+
+ public Map<String, AtomicHighLevelStateHandler> getAtomicHighLevelStates()
+ {
+ return atomicHighLevelStateHandlersUnmodifiable;
+ }
+
private static void checkHighLevelStateIDPart(String stateIDPart)
{
if (stateIDPart.indexOf('.') != -1)
package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import net.mograsim.logic.core.types.Bit;
public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
{
- private SubmodelComponent component;
+ private final SubmodelComponent component;
private final List<String> vectorPartTargets;
+ private final List<String> vectorPartTargetsUnmodifiable;
private final List<Integer> vectorPartLengthes;
+ private final List<Integer> vectorPartLengthesUnmodifiable;
private int length;
public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
{
this.component = context.component;
this.vectorPartTargets = new ArrayList<>();
+ this.vectorPartTargetsUnmodifiable = Collections.unmodifiableList(vectorPartTargets);
this.vectorPartLengthes = new ArrayList<>();
+ this.vectorPartLengthesUnmodifiable = Collections.unmodifiableList(vectorPartLengthes);
if (params != null)
setVectorParts(params.vectorPartTargets, params.vectorPartLengthes);
}
length += lengthes.stream().mapToInt(Integer::intValue).sum();
}
+ public List<String> getVectorPartTargets()
+ {
+ return vectorPartTargetsUnmodifiable;
+ }
+
+ public List<Integer> getVectorPartLenghtes()
+ {
+ return vectorPartLengthesUnmodifiable;
+ }
+
@Override
public Object getHighLevelState()
{
if (params.delegateTarget == null)
setDelegateTarget(parentComponent);
else
- setDelegateTarget(parentComponent.submodel.getComponentsByName().get(params.delegateTarget));
+ {
+ ModelComponent delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+ if (delegateTarget == null)
+ throw new NullPointerException("No subcomponent with name " + params.delegateTarget);
+ setDelegateTarget(delegateTarget);
+ }
setSubStateID(params.subStateID);
}
+ parentComponent.submodel.addComponentRemovedListener(c ->
+ {
+ if (delegateTarget == c)
+ delegateTarget = null;
+ });
}
public void set(ModelComponent delegateTarget, String subStateID)
this.delegateTarget = delegateTarget;
}
+ public ModelComponent getDelegateTarget()
+ {
+ return delegateTarget;
+ }
+
public void setSubStateID(String subStateID)
{
this.subStateID = subStateID;
}
+ public String getSubStateID()
+ {
+ return subStateID;
+ }
+
@Override
public Object getHighLevelState()
{
+ if (delegateTarget == null)
+ throw new IllegalStateException("Delegating to a component that was destroyed");
return delegateTarget.getHighLevelState(subStateID);
}
@Override
public void setHighLevelState(Object newState)
{
+ if (delegateTarget == null)
+ throw new IllegalStateException("Delegating to a component that was destroyed");
delegateTarget.setHighLevelState(subStateID, newState);
}
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;
public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
{
- private SubmodelComponent component;
+ private final SubmodelComponent component;
private int logicWidth;
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, 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<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
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()
{
if (params.delegateTarget == null)
setDelegateTarget(parentComponent);
else
- this.delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+ {
+ ModelComponent delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+ if (delegateTarget == null)
+ throw new NullPointerException("No subcomponent with name " + params.delegateTarget);
+ setDelegateTarget(delegateTarget);
+ }
setPrefix(params.prefix);
}
+ parentComponent.submodel.addComponentRemovedListener(c ->
+ {
+ if (delegateTarget == c)
+ delegateTarget = null;
+ });
}
public void set(ModelComponent delegateTarget, String prefix)
this.delegateTarget = delegateTarget;
}
+ public ModelComponent getDelegateTarget()
+ {
+ return delegateTarget;
+ }
+
public void setPrefix(String prefix)
{
this.prefix = prefix;
}
+ public String getPrefix()
+ {
+ return prefix;
+ }
+
@Override
public Object getHighLevelState(String subStateID)
{
+ if (delegateTarget == null)
+ throw new IllegalStateException("Delegating to a component that was destroyed");
return delegateTarget.getHighLevelState(getDelegateTargetHighLevelStateID(subStateID));
}
@Override
public void setHighLevelState(String subStateID, Object newState)
{
+ if (delegateTarget == null)
+ throw new IllegalStateException("Delegating to a component that was destroyed");
delegateTarget.setHighLevelState(getDelegateTargetHighLevelStateID(subStateID), newState);
}
this.pinLabelMargin = params.pinLabelMargin;
if (params.pinNamePositions != null)
params.pinNamePositions.forEach(this::setPinPosition);
+ component.addPinRemovedListener(p -> setPinPosition(p, null));
}
public void setPinPosition(String pinName, Position position)