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