Merge remote-tracking branch 'origin/development' into development
[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.List;
5
6 import net.mograsim.logic.core.types.Bit;
7 import net.mograsim.logic.core.types.BitVector;
8 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
9 import net.mograsim.logic.model.serializing.IdentifierGetter;
10 import net.mograsim.logic.model.snippets.SnippetDefinintion;
11 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext;
12 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
13
14 public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
15 {
16         private SubmodelComponent component;
17         private final List<String> vectorPartTargets;
18         private final List<Integer> vectorPartLengthes;
19
20         public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
21         {
22                 this(context, null);
23         }
24
25         public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context,
26                         BitVectorSplittingAtomicHighLevelStateHandlerParams params)
27         {
28                 this.component = context.component;
29                 this.vectorPartTargets = new ArrayList<>();
30                 this.vectorPartLengthes = new ArrayList<>();
31                 if (params != null)
32                         setVectorParts(params.vectorPartTargets, params.vectorPartLengthes);
33         }
34
35         public void set(List<String> targets, List<Integer> lengthes)
36         {
37                 setVectorParts(targets, lengthes);
38         }
39
40         public void addVectorPart(String target, int length)
41         {
42                 vectorPartTargets.add(target);
43                 vectorPartLengthes.add(length);
44         }
45
46         public void clearVectorParts()
47         {
48                 vectorPartTargets.clear();
49                 vectorPartLengthes.clear();
50         }
51
52         private void setVectorParts(List<String> targets, List<Integer> lengthes)
53         {
54                 clearVectorParts();
55                 if (targets.size() != lengthes.size())
56                         throw new IllegalArgumentException("Targets list and lenghtes list have different sizes");
57                 vectorPartTargets.addAll(targets);
58                 vectorPartLengthes.addAll(lengthes);
59         }
60
61         @Override
62         public Object getHighLevelState()
63         {
64                 BitVector result = BitVector.of();
65                 for (int partIndex = 0; partIndex < vectorPartTargets.size(); partIndex++)
66                 {
67                         Object subStateUncasted = component.getHighLevelState(vectorPartTargets.get(partIndex));
68                         BitVector vectorPart;
69                         if (subStateUncasted instanceof Bit)
70                                 vectorPart = BitVector.of((Bit) subStateUncasted);
71                         else
72                                 vectorPart = (BitVector) subStateUncasted;
73                         if (vectorPart.length() != vectorPartLengthes.get(partIndex))
74                                 throw new IllegalArgumentException(
75                                                 "Illegal vector part length: " + vectorPart.length() + "; expected " + vectorPartLengthes.get(partIndex));
76                         result = vectorPart.concat(result);
77                 }
78                 return result;
79         }
80
81         @Override
82         public void setHighLevelState(Object newState)
83         {
84                 BitVector newStateCasted = (BitVector) newState;
85                 for (int partIndex = vectorPartTargets.size() - 1, bitIndex = 0; partIndex >= 0; partIndex--)
86                 {
87                         int vectorPartLength = vectorPartLengthes.get(partIndex);
88                         BitVector vectorPart = newStateCasted.subVector(bitIndex, bitIndex + vectorPartLength);
89                         component.setHighLevelState(vectorPartTargets.get(partIndex), vectorPart);
90                         bitIndex += vectorPartLength;
91                 }
92         }
93
94         @Override
95         public BitVectorSplittingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifierGetter idGetter)
96         {
97                 BitVectorSplittingAtomicHighLevelStateHandlerParams params = new BitVectorSplittingAtomicHighLevelStateHandlerParams();
98                 params.vectorPartTargets = new ArrayList<>(vectorPartTargets);
99                 params.vectorPartLengthes = new ArrayList<>(vectorPartLengthes);
100                 return params;
101         }
102
103         public static class BitVectorSplittingAtomicHighLevelStateHandlerParams
104         {
105                 public List<String> vectorPartTargets;
106                 public List<Integer> vectorPartLengthes;
107         }
108
109         static
110         {
111                 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier
112                                 .setSnippetSupplier(BitVectorSplittingAtomicHighLevelStateHandler.class.getCanonicalName(), SnippetDefinintion.create(
113                                                 BitVectorSplittingAtomicHighLevelStateHandlerParams.class, BitVectorSplittingAtomicHighLevelStateHandler::new));
114         }
115 }