Changed BitVectorSplittingAtomicHighLevelStateHandler's part order
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / snippets / highlevelstatehandlers / standard / atomic / BitVectorSplittingAtomicHighLevelStateHandler.java
1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6
7 import net.mograsim.logic.core.types.Bit;
8 import net.mograsim.logic.core.types.BitVector;
9 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
10 import net.mograsim.logic.model.serializing.IdentifyParams;
11 import net.mograsim.logic.model.snippets.SnippetDefinintion;
12 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
13 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
14
15 public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
16 {
17         private final SubmodelComponent component;
18         private final List<String> vectorPartTargets;
19         private final List<String> vectorPartTargetsUnmodifiable;
20         private final List<Integer> vectorPartLengthes;
21         private final List<Integer> vectorPartLengthesUnmodifiable;
22         private int length;
23
24         public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
25         {
26                 this(context, null);
27         }
28
29         public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context,
30                         BitVectorSplittingAtomicHighLevelStateHandlerParams params)
31         {
32                 this.component = context.component;
33                 this.vectorPartTargets = new ArrayList<>();
34                 this.vectorPartTargetsUnmodifiable = Collections.unmodifiableList(vectorPartTargets);
35                 this.vectorPartLengthes = new ArrayList<>();
36                 this.vectorPartLengthesUnmodifiable = Collections.unmodifiableList(vectorPartLengthes);
37                 if (params != null)
38                         setVectorParts(params.vectorPartTargets, params.vectorPartLengthes);
39         }
40
41         public void set(List<String> targets, List<Integer> lengthes)
42         {
43                 setVectorParts(targets, lengthes);
44         }
45
46         public void addVectorPart(String target, int length)
47         {
48                 vectorPartTargets.add(target);
49                 vectorPartLengthes.add(length);
50                 this.length += length;
51         }
52
53         public void clearVectorParts()
54         {
55                 vectorPartTargets.clear();
56                 vectorPartLengthes.clear();
57                 length = 0;
58         }
59
60         private void setVectorParts(List<String> targets, List<Integer> lengthes)
61         {
62                 clearVectorParts();
63                 if (targets.size() != lengthes.size())
64                         throw new IllegalArgumentException("Targets list and lengthes list have different sizes");
65                 vectorPartTargets.addAll(targets);
66                 vectorPartLengthes.addAll(lengthes);
67                 length += lengthes.stream().mapToInt(Integer::intValue).sum();
68         }
69
70         public List<String> getVectorPartTargets()
71         {
72                 return vectorPartTargetsUnmodifiable;
73         }
74
75         public List<Integer> getVectorPartLenghtes()
76         {
77                 return vectorPartLengthesUnmodifiable;
78         }
79
80         @Override
81         public Object getHighLevelState()
82         {
83                 BitVector result = BitVector.of();
84                 for (int partIndex = 0; partIndex < vectorPartTargets.size(); partIndex++)
85                 {
86                         Object subStateUncasted = component.getHighLevelState(vectorPartTargets.get(partIndex));
87                         BitVector vectorPart;
88                         if (subStateUncasted instanceof Bit)
89                                 vectorPart = BitVector.of((Bit) subStateUncasted);
90                         else
91                                 vectorPart = (BitVector) subStateUncasted;
92                         if (vectorPart.length() != vectorPartLengthes.get(partIndex))
93                                 throw new IllegalArgumentException(
94                                                 "Incorrect vector part length: " + vectorPart.length() + "; expected " + vectorPartLengthes.get(partIndex));
95                         result = result.concat(vectorPart);
96                 }
97                 return result;
98         }
99
100         @Override
101         public void setHighLevelState(Object newState)
102         {
103                 BitVector newStateCasted = (BitVector) newState;
104                 if (newStateCasted.length() != length)
105                         throw new IllegalArgumentException("Incorrect vector length: " + newStateCasted.length() + "; expected " + length);
106                 for (int partIndex = 0, bitIndex = 0; partIndex < vectorPartTargets.size(); partIndex++)
107                 {
108                         int vectorPartLength = vectorPartLengthes.get(partIndex);
109                         BitVector vectorPart = newStateCasted.subVector(bitIndex, bitIndex + vectorPartLength);
110                         component.setHighLevelState(vectorPartTargets.get(partIndex), vectorPart);
111                         bitIndex += vectorPartLength;
112                 }
113         }
114
115         @Override
116         public String getIDForSerializing(IdentifyParams idParams)
117         {
118                 return "bitVectorSplitting";
119         }
120
121         @Override
122         public BitVectorSplittingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
123         {
124                 BitVectorSplittingAtomicHighLevelStateHandlerParams params = new BitVectorSplittingAtomicHighLevelStateHandlerParams();
125                 params.vectorPartTargets = new ArrayList<>(vectorPartTargets);
126                 params.vectorPartLengthes = new ArrayList<>(vectorPartLengthes);
127                 return params;
128         }
129
130         public static class BitVectorSplittingAtomicHighLevelStateHandlerParams
131         {
132                 public List<String> vectorPartTargets;
133                 public List<Integer> vectorPartLengthes;
134         }
135
136         static
137         {
138                 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier
139                                 .setSnippetSupplier(BitVectorSplittingAtomicHighLevelStateHandler.class.getCanonicalName(), SnippetDefinintion.create(
140                                                 BitVectorSplittingAtomicHighLevelStateHandlerParams.class, BitVectorSplittingAtomicHighLevelStateHandler::new));
141         }
142 }