Added a state to SimpleRectangularHardcodedGUIComponent.recalculate
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / modeladapter / componentadapters / SimpleRectangularHardcodedGUIComponentAdapter.java
1 package net.mograsim.logic.model.modeladapter.componentadapters;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.concurrent.atomic.AtomicReference;
6 import java.util.function.Function;
7
8 import net.mograsim.logic.core.LogicObserver;
9 import net.mograsim.logic.core.timeline.Timeline;
10 import net.mograsim.logic.core.wires.Wire;
11 import net.mograsim.logic.core.wires.Wire.ReadEnd;
12 import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
13 import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
14 import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent.Usage;
15 import net.mograsim.logic.model.model.wires.Pin;
16 import net.mograsim.logic.model.modeladapter.LogicModelParameters;
17
18 //TODO support HighLevelStates
19 public class SimpleRectangularHardcodedGUIComponentAdapter implements ComponentAdapter<SimpleRectangularHardcodedGUIComponent>
20 {
21         private final Function<SimpleRectangularHardcodedGUIComponent, RecalculateFunction> recalculateFunctionGenerator;
22
23         public SimpleRectangularHardcodedGUIComponentAdapter(
24                         Function<SimpleRectangularHardcodedGUIComponent, RecalculateFunction> recalculateFunctionGenerator)
25         {
26                 this.recalculateFunctionGenerator = recalculateFunctionGenerator;
27         }
28
29         @Override
30         public Class<SimpleRectangularHardcodedGUIComponent> getSupportedClass()
31         {
32                 return SimpleRectangularHardcodedGUIComponent.class;
33         }
34
35         @Override
36         public void createAndLinkComponent(Timeline timeline, LogicModelParameters params, SimpleRectangularHardcodedGUIComponent guiComponent,
37                         Map<Pin, Wire> logicWiresPerPin)
38         {
39                 RecalculateFunction recalculate = recalculateFunctionGenerator.apply(guiComponent);
40                 Map<String, ReadEnd> readEnds = new HashMap<>();
41                 Map<String, ReadWriteEnd> readWriteEnds = new HashMap<>();
42
43                 AtomicReference<Object> state = new AtomicReference<>();
44
45                 LogicObserver logicObs = c -> state.set(recalculate.recalculate(state.get(), readEnds, readWriteEnds));
46
47                 for (Pin pin : guiComponent.getPins().values())
48                 {
49                         Wire wire = logicWiresPerPin.get(pin);
50                         ReadEnd end;
51                         if (guiComponent.getPinUsage(pin) != Usage.INPUT)
52                         {
53                                 ReadWriteEnd rwEnd = wire.createReadWriteEnd();
54                                 readWriteEnds.put(pin.name, rwEnd);
55                                 end = rwEnd;
56                         } else
57                                 end = wire.createReadOnlyEnd();
58                         readEnds.put(pin.name, end);
59                         if (guiComponent.getPinUsage(pin) != Usage.OUTPUT)
60                                 end.registerObserver(logicObs);
61                 }
62         }
63
64         public static interface RecalculateFunction
65         {
66                 public Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds);
67         }
68 }