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