MPROMEditor now calls its columns "Opcode" and "muPC"
[Mograsim.git] / plugins / net.mograsim.logic.model / src / net / mograsim / logic / model / snippets / highlevelstatehandlers / standard / StandardHighLevelStateHandler.java
1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.Map.Entry;
7 import java.util.TreeMap;
8 import java.util.function.BiFunction;
9 import java.util.function.Consumer;
10 import java.util.function.Function;
11
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.HighLevelStateHandler;
15 import net.mograsim.logic.model.snippets.SnippetDefinintion;
16 import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers;
17 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler;
18 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler.AtomicHighLevelStateHandlerParams;
19 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler;
20 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler.SubcomponentHighLevelStateHandlerParams;
21
22 public class StandardHighLevelStateHandler implements HighLevelStateHandler
23 {
24         private final SubmodelComponent component;
25         private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlers;
26         private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlersUnmodifiable;
27         private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlers;
28         private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlersUnmodifiable;
29
30         public StandardHighLevelStateHandler(SubmodelComponent component)
31         {
32                 this(component, null);
33         }
34
35         public StandardHighLevelStateHandler(SubmodelComponent component, StandardHighLevelStateHandlerParams params)
36         {
37                 this.component = component;
38                 this.subcomponentHighLevelStateHandlers = new HashMap<>();
39                 this.subcomponentHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(subcomponentHighLevelStateHandlers);
40                 this.atomicHighLevelStateHandlers = new HashMap<>();
41                 this.atomicHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(atomicHighLevelStateHandlers);
42                 if (params != null)
43                 {
44                         params.subcomponentHighLevelStates.forEach(this::addSubcomponentHighLevelState);
45                         params.atomicHighLevelStates.forEach(this::addAtomicHighLevelState);
46                 }
47         }
48
49         public SubcomponentHighLevelStateHandler addSubcomponentHighLevelState(String subcomponentStateID,
50                         SubcomponentHighLevelStateHandlerParams handlerParams)
51         {
52                 return addSubcomponentHighLevelState(subcomponentStateID,
53                                 StandardHighLevelStateHandlerSnippetSuppliers.subcomponentHandlerSupplier.getSnippetSupplier(handlerParams.id)::create,
54                                 handlerParams.params);
55         }
56
57         public <P, H extends SubcomponentHighLevelStateHandler> H addSubcomponentHighLevelState(String subcomponentStateID,
58                         BiFunction<SubmodelComponent, P, H> handlerConstructor, P handlerParams)
59         {
60                 return addSubcomponentHighLevelState(subcomponentStateID, c -> handlerConstructor.apply(c, handlerParams));
61         }
62
63         public <H extends SubcomponentHighLevelStateHandler> H addSubcomponentHighLevelState(String subcomponentStateID,
64                         Function<SubmodelComponent, H> handlerConstructor)
65         {
66                 H handler = handlerConstructor.apply(component);
67                 addSubcomponentHighLevelState(subcomponentStateID, handler);
68                 return handler;
69         }
70
71         public void addSubcomponentHighLevelState(String subcomponentStateID, SubcomponentHighLevelStateHandler handler)
72         {
73                 checkHighLevelStateIDPart(subcomponentStateID);
74                 subcomponentHighLevelStateHandlers.put(subcomponentStateID, handler);
75         }
76
77         public void removeSubcomponentHighLevelState(String subcomponentStateID)
78         {
79                 checkHighLevelStateIDPart(subcomponentStateID);
80                 subcomponentHighLevelStateHandlers.remove(subcomponentStateID);
81         }
82
83         public Map<String, SubcomponentHighLevelStateHandler> getSubcomponentHighLevelStates()
84         {
85                 return subcomponentHighLevelStateHandlersUnmodifiable;
86         }
87
88         public AtomicHighLevelStateHandler addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandlerParams handlerParams)
89         {
90                 return addAtomicHighLevelState(atomicStateID,
91                                 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.getSnippetSupplier(handlerParams.id)::create,
92                                 handlerParams.params);
93         }
94
95         public <P, H extends AtomicHighLevelStateHandler> H addAtomicHighLevelState(String subcomponentStateID,
96                         BiFunction<SubmodelComponent, P, H> handlerConstructor, P handlerParams)
97         {
98                 return addAtomicHighLevelState(subcomponentStateID, c -> handlerConstructor.apply(c, handlerParams));
99         }
100
101         public <H extends AtomicHighLevelStateHandler> H addAtomicHighLevelState(String subcomponentStateID,
102                         Function<SubmodelComponent, H> handlerConstructor)
103         {
104                 H handler = handlerConstructor.apply(component);
105                 addAtomicHighLevelState(subcomponentStateID, handler);
106                 return handler;
107         }
108
109         public void addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandler handler)
110         {
111                 checkHighLevelStateIDPart(atomicStateID);
112                 atomicHighLevelStateHandlers.put(atomicStateID, handler);
113         }
114
115         public void removeAtomicHighLevelState(String atomicStateID)
116         {
117                 checkHighLevelStateIDPart(atomicStateID);
118                 atomicHighLevelStateHandlers.remove(atomicStateID);
119         }
120
121         public Map<String, AtomicHighLevelStateHandler> getAtomicHighLevelStates()
122         {
123                 return atomicHighLevelStateHandlersUnmodifiable;
124         }
125
126         private static void checkHighLevelStateIDPart(String stateIDPart)
127         {
128                 if (stateIDPart.indexOf('.') != -1)
129                         throw new IllegalArgumentException("Illegal high level state ID part (contains dot): " + stateIDPart);
130         }
131
132         @Override
133         public Object get(String stateID)
134         {
135                 int indexOfDot = stateID.indexOf('.');
136                 if (indexOfDot == -1)
137                 {
138                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
139                         if (handler != null)
140                                 return handler.getHighLevelState();
141                 } else
142                 {
143                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
144                         if (handler != null)
145                                 return handler.getHighLevelState(stateID.substring(indexOfDot + 1));
146                 }
147                 throw new IllegalArgumentException("No high level state with ID " + stateID);
148         }
149
150         @Override
151         public void set(String stateID, Object newState)
152         {
153                 int indexOfDot = stateID.indexOf('.');
154                 if (indexOfDot == -1)
155                 {
156                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
157                         if (handler != null)
158                                 handler.setHighLevelState(newState);
159                         else
160                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
161                 } else
162                 {
163                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
164                         if (handler != null)
165                                 handler.setHighLevelState(stateID.substring(indexOfDot + 1), newState);
166                         else
167                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
168                 }
169         }
170
171         @Override
172         public void addListener(String stateID, Consumer<Object> stateChanged)
173         {
174                 int indexOfDot = stateID.indexOf('.');
175                 if (indexOfDot == -1)
176                 {
177                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
178                         if (handler != null)
179                                 handler.addListener(stateChanged);
180                         else
181                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
182                 } else
183                 {
184                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
185                         if (handler != null)
186                                 handler.addListener(stateID.substring(indexOfDot + 1), stateChanged);
187                         else
188                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
189                 }
190         }
191
192         @Override
193         public void removeListener(String stateID, Consumer<Object> stateChanged)
194         {
195                 int indexOfDot = stateID.indexOf('.');
196                 if (indexOfDot == -1)
197                 {
198                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
199                         if (handler != null)
200                                 handler.removeListener(stateChanged);
201                         else
202                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
203                 } else
204                 {
205                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
206                         if (handler != null)
207                                 handler.removeListener(stateID.substring(indexOfDot + 1), stateChanged);
208                         else
209                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
210                 }
211         }
212
213         @Override
214         public String getIDForSerializing(IdentifyParams idParams)
215         {
216                 return "standard";
217         }
218
219         @Override
220         public StandardHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
221         {
222                 StandardHighLevelStateHandlerParams params = new StandardHighLevelStateHandlerParams();
223                 params.subcomponentHighLevelStates = new TreeMap<>();
224                 params.atomicHighLevelStates = new TreeMap<>();
225                 for (Entry<String, SubcomponentHighLevelStateHandler> e : subcomponentHighLevelStateHandlers.entrySet())
226                 {
227                         String stateID = e.getKey();
228                         SubcomponentHighLevelStateHandler handler = e.getValue();
229                         SubcomponentHighLevelStateHandlerParams handlerParams = new SubcomponentHighLevelStateHandlerParams();
230                         handlerParams.id = handler.getIDForSerializing(idParams);
231                         handlerParams.params = handler.getParamsForSerializingJSON(idParams);
232                         params.subcomponentHighLevelStates.put(stateID, handlerParams);
233                 }
234                 for (Entry<String, AtomicHighLevelStateHandler> e : atomicHighLevelStateHandlers.entrySet())
235                 {
236                         String stateID = e.getKey();
237                         AtomicHighLevelStateHandler handler = e.getValue();
238                         AtomicHighLevelStateHandlerParams handlerParams = new AtomicHighLevelStateHandlerParams();
239                         handlerParams.id = handler.getIDForSerializing(idParams);
240                         handlerParams.params = handler.getParamsForSerializingJSON(idParams);
241                         params.atomicHighLevelStates.put(stateID, handlerParams);
242                 }
243                 return params;
244         }
245
246         public static class StandardHighLevelStateHandlerParams
247         {
248                 public Map<String, SubcomponentHighLevelStateHandlerParams> subcomponentHighLevelStates;
249                 public Map<String, AtomicHighLevelStateHandlerParams> atomicHighLevelStates;
250         }
251
252         static
253         {
254                 SubmodelComponentSnippetSuppliers.highLevelStateHandlerSupplier.setSnippetSupplier(
255                                 StandardHighLevelStateHandler.class.getCanonicalName(),
256                                 SnippetDefinintion.create(StandardHighLevelStateHandlerParams.class, StandardHighLevelStateHandler::new));
257         }
258 }