HighLevelStates are now sorted in JSONs
[Mograsim.git] / 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.Function;
10
11 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
12 import net.mograsim.logic.model.serializing.IdentifyParams;
13 import net.mograsim.logic.model.snippets.HighLevelStateHandler;
14 import net.mograsim.logic.model.snippets.SnippetDefinintion;
15 import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers;
16 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler;
17 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler.AtomicHighLevelStateHandlerParams;
18 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler;
19 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler.SubcomponentHighLevelStateHandlerParams;
20
21 public class StandardHighLevelStateHandler implements HighLevelStateHandler
22 {
23         private final SubmodelComponent component;
24         private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlers;
25         private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlersUnmodifiable;
26         private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlers;
27         private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlersUnmodifiable;
28
29         public StandardHighLevelStateHandler(SubmodelComponent component)
30         {
31                 this(component, null);
32         }
33
34         public StandardHighLevelStateHandler(SubmodelComponent component, StandardHighLevelStateHandlerParams params)
35         {
36                 this.component = component;
37                 this.subcomponentHighLevelStateHandlers = new HashMap<>();
38                 this.subcomponentHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(subcomponentHighLevelStateHandlers);
39                 this.atomicHighLevelStateHandlers = new HashMap<>();
40                 this.atomicHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(atomicHighLevelStateHandlers);
41                 if (params != null)
42                 {
43                         params.subcomponentHighLevelStates.forEach(this::addSubcomponentHighLevelState);
44                         params.atomicHighLevelStates.forEach(this::addAtomicHighLevelState);
45                 }
46         }
47
48         public SubcomponentHighLevelStateHandler addSubcomponentHighLevelState(String subcomponentStateID,
49                         SubcomponentHighLevelStateHandlerParams handlerParams)
50         {
51                 return addSubcomponentHighLevelState(subcomponentStateID,
52                                 StandardHighLevelStateHandlerSnippetSuppliers.subcomponentHandlerSupplier.getSnippetSupplier(handlerParams.id)::create,
53                                 handlerParams.params);
54         }
55
56         public <P, H extends SubcomponentHighLevelStateHandler> H addSubcomponentHighLevelState(String subcomponentStateID,
57                         BiFunction<HighLevelStateHandlerContext, P, H> handlerConstructor, P handlerParams)
58         {
59                 return addSubcomponentHighLevelState(subcomponentStateID, c -> handlerConstructor.apply(c, handlerParams));
60         }
61
62         public <H extends SubcomponentHighLevelStateHandler> H addSubcomponentHighLevelState(String subcomponentStateID,
63                         Function<HighLevelStateHandlerContext, H> handlerConstructor)
64         {
65                 HighLevelStateHandlerContext context = new HighLevelStateHandlerContext(component, subcomponentStateID);
66                 H handler = handlerConstructor.apply(context);
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<HighLevelStateHandlerContext, 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<HighLevelStateHandlerContext, H> handlerConstructor)
103         {
104                 HighLevelStateHandlerContext context = new HighLevelStateHandlerContext(component, subcomponentStateID);
105                 H handler = handlerConstructor.apply(context);
106                 addAtomicHighLevelState(subcomponentStateID, handler);
107                 return handler;
108         }
109
110         public void addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandler handler)
111         {
112                 checkHighLevelStateIDPart(atomicStateID);
113                 atomicHighLevelStateHandlers.put(atomicStateID, handler);
114         }
115
116         public void removeAtomicHighLevelState(String atomicStateID)
117         {
118                 checkHighLevelStateIDPart(atomicStateID);
119                 atomicHighLevelStateHandlers.remove(atomicStateID);
120         }
121
122         public Map<String, AtomicHighLevelStateHandler> getAtomicHighLevelStates()
123         {
124                 return atomicHighLevelStateHandlersUnmodifiable;
125         }
126
127         private static void checkHighLevelStateIDPart(String stateIDPart)
128         {
129                 if (stateIDPart.indexOf('.') != -1)
130                         throw new IllegalArgumentException("Illegal high level state ID part (contains dot): " + stateIDPart);
131         }
132
133         @Override
134         public Object getHighLevelState(String stateID)
135         {
136                 int indexOfDot = stateID.indexOf('.');
137                 if (indexOfDot == -1)
138                 {
139                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
140                         if (handler != null)
141                                 return handler.getHighLevelState();
142                 } else
143                 {
144                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
145                         if (handler != null)
146                                 return handler.getHighLevelState(stateID.substring(indexOfDot + 1));
147                 }
148                 throw new IllegalArgumentException("No high level state with ID " + stateID);
149         }
150
151         @Override
152         public void setHighLevelState(String stateID, Object newState)
153         {
154                 int indexOfDot = stateID.indexOf('.');
155                 if (indexOfDot == -1)
156                 {
157                         AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID);
158                         if (handler != null)
159                                 handler.setHighLevelState(newState);
160                         else
161                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
162                 } else
163                 {
164                         SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot));
165                         if (handler != null)
166                                 handler.setHighLevelState(stateID.substring(indexOfDot + 1), newState);
167                         else
168                                 throw new IllegalArgumentException("No high level state with ID " + stateID);
169                 }
170         }
171
172         @Override
173         public String getIDForSerializing(IdentifyParams idParams)
174         {
175                 return "standard";
176         }
177
178         @Override
179         public StandardHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
180         {
181                 StandardHighLevelStateHandlerParams params = new StandardHighLevelStateHandlerParams();
182                 params.subcomponentHighLevelStates = new TreeMap<>();
183                 params.atomicHighLevelStates = new TreeMap<>();
184                 for (Entry<String, SubcomponentHighLevelStateHandler> e : subcomponentHighLevelStateHandlers.entrySet())
185                 {
186                         String stateID = e.getKey();
187                         SubcomponentHighLevelStateHandler handler = e.getValue();
188                         SubcomponentHighLevelStateHandlerParams handlerParams = new SubcomponentHighLevelStateHandlerParams();
189                         handlerParams.id = handler.getIDForSerializing(idParams);
190                         handlerParams.params = handler.getParamsForSerializingJSON(idParams);
191                         params.subcomponentHighLevelStates.put(stateID, handlerParams);
192                 }
193                 for (Entry<String, AtomicHighLevelStateHandler> e : atomicHighLevelStateHandlers.entrySet())
194                 {
195                         String stateID = e.getKey();
196                         AtomicHighLevelStateHandler handler = e.getValue();
197                         AtomicHighLevelStateHandlerParams handlerParams = new AtomicHighLevelStateHandlerParams();
198                         handlerParams.id = handler.getIDForSerializing(idParams);
199                         handlerParams.params = handler.getParamsForSerializingJSON(idParams);
200                         params.atomicHighLevelStates.put(stateID, handlerParams);
201                 }
202                 return params;
203         }
204
205         public static class StandardHighLevelStateHandlerParams
206         {
207                 public Map<String, SubcomponentHighLevelStateHandlerParams> subcomponentHighLevelStates;
208                 public Map<String, AtomicHighLevelStateHandlerParams> atomicHighLevelStates;
209         }
210
211         static
212         {
213                 SubmodelComponentSnippetSuppliers.highLevelStateHandlerSupplier.setSnippetSupplier(
214                                 StandardHighLevelStateHandler.class.getCanonicalName(),
215                                 SnippetDefinintion.create(StandardHighLevelStateHandlerParams.class, StandardHighLevelStateHandler::new));
216         }
217 }