1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
8 import java.util.function.Consumer;
10 import net.mograsim.logic.core.types.Bit;
11 import net.mograsim.logic.core.types.BitVector;
12 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
13 import net.mograsim.logic.model.serializing.IdentifyParams;
14 import net.mograsim.logic.model.snippets.SnippetDefinintion;
15 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
17 public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
19 private final SubmodelComponent component;
20 private final List<String> vectorPartTargets;
21 private final List<String> vectorPartTargetsUnmodifiable;
22 private final List<Integer> vectorPartLengthes;
23 private final List<Integer> vectorPartLengthesUnmodifiable;
26 private final Map<Consumer<Object>, Consumer<Object>> targetListeners;
28 public BitVectorSplittingAtomicHighLevelStateHandler(SubmodelComponent component)
30 this(component, null);
33 public BitVectorSplittingAtomicHighLevelStateHandler(SubmodelComponent component,
34 BitVectorSplittingAtomicHighLevelStateHandlerParams params)
36 this.component = component;
37 this.vectorPartTargets = new ArrayList<>();
38 this.vectorPartTargetsUnmodifiable = Collections.unmodifiableList(vectorPartTargets);
39 this.vectorPartLengthes = new ArrayList<>();
40 this.vectorPartLengthesUnmodifiable = Collections.unmodifiableList(vectorPartLengthes);
42 this.targetListeners = new HashMap<>();
45 setVectorParts(params.vectorPartTargets, params.vectorPartLengthes);
48 public void set(List<String> targets, List<Integer> lengthes)
50 setVectorParts(targets, lengthes);
53 public void addVectorPart(String target, int length)
55 vectorPartTargets.add(target);
56 vectorPartLengthes.add(length);
57 this.length += length;
60 public void clearVectorParts()
62 vectorPartTargets.clear();
63 vectorPartLengthes.clear();
67 private void setVectorParts(List<String> targets, List<Integer> lengthes)
70 if (targets.size() != lengthes.size())
71 throw new IllegalArgumentException("Targets list and lengthes list have different sizes");
72 vectorPartTargets.addAll(targets);
73 vectorPartLengthes.addAll(lengthes);
74 length += lengthes.stream().mapToInt(Integer::intValue).sum();
77 public List<String> getVectorPartTargets()
79 return vectorPartTargetsUnmodifiable;
82 public List<Integer> getVectorPartLenghtes()
84 return vectorPartLengthesUnmodifiable;
88 public Object getHighLevelState()
90 BitVector result = BitVector.of();
91 for (int partIndex = 0; partIndex < vectorPartTargets.size(); partIndex++)
93 Object subStateUncasted = component.getHighLevelState(vectorPartTargets.get(partIndex));
95 if (subStateUncasted instanceof Bit)
96 vectorPart = BitVector.of((Bit) subStateUncasted);
98 vectorPart = (BitVector) subStateUncasted;
99 if (vectorPart.length() != vectorPartLengthes.get(partIndex))
100 throw new IllegalArgumentException(
101 "Incorrect vector part length: " + vectorPart.length() + "; expected " + vectorPartLengthes.get(partIndex));
102 result = result.concat(vectorPart);
108 public void setHighLevelState(Object newState)
110 BitVector newStateCasted = (BitVector) newState;
111 if (newStateCasted.length() != length)
112 throw new IllegalArgumentException("Incorrect vector length: " + newStateCasted.length() + "; expected " + length);
113 for (int partIndex = 0, bitIndex = 0; partIndex < vectorPartTargets.size(); partIndex++)
115 int vectorPartLength = vectorPartLengthes.get(partIndex);
116 BitVector vectorPart = newStateCasted.subVector(bitIndex, bitIndex + vectorPartLength);
117 component.setHighLevelState(vectorPartTargets.get(partIndex), vectorPart);
118 bitIndex += vectorPartLength;
123 public void addListener(Consumer<Object> stateChanged)
125 if (targetListeners.get(stateChanged) != null)
126 // this listener is/was already registered
129 Consumer<Object> targetListener = o -> stateChanged.accept(getHighLevelState());
130 targetListeners.put(stateChanged, targetListener);
132 for (String target : vectorPartTargets)
133 component.addHighLevelStateListener(target, targetListener);
137 public void removeListener(Consumer<Object> stateChanged)
139 Consumer<Object> targetListener = targetListeners.get(stateChanged);
140 if (targetListener == null)
141 // this listener is/was not registered
144 for (String target : vectorPartTargets)
145 component.removeHighLevelStateListener(target, targetListener);
149 public String getIDForSerializing(IdentifyParams idParams)
151 return "bitVectorSplitting";
155 public BitVectorSplittingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
157 BitVectorSplittingAtomicHighLevelStateHandlerParams params = new BitVectorSplittingAtomicHighLevelStateHandlerParams();
158 params.vectorPartTargets = new ArrayList<>(vectorPartTargets);
159 params.vectorPartLengthes = new ArrayList<>(vectorPartLengthes);
163 public static class BitVectorSplittingAtomicHighLevelStateHandlerParams
165 public List<String> vectorPartTargets;
166 public List<Integer> vectorPartLengthes;
171 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier
172 .setSnippetSupplier(BitVectorSplittingAtomicHighLevelStateHandler.class.getCanonicalName(), SnippetDefinintion.create(
173 BitVectorSplittingAtomicHighLevelStateHandlerParams.class, BitVectorSplittingAtomicHighLevelStateHandler::new));