c06ec1494bd47e903d6ac34fa2dd14d736513f7e
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / atomic / SimpleRectangularHardcodedGUIComponent.java
1 package net.mograsim.logic.model.model.components.atomic;
2
3 import java.util.Map;
4 import java.util.concurrent.atomic.AtomicReference;
5
6 import net.haspamelodica.swt.helper.gcs.GeneralGC;
7 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
8 import net.mograsim.logic.core.wires.Wire.ReadEnd;
9 import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
10 import net.mograsim.logic.model.model.ViewModelModifiable;
11 import net.mograsim.logic.model.model.components.GUIComponent;
12 import net.mograsim.logic.model.model.wires.Pin;
13 import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
14 import net.mograsim.logic.model.modeladapter.componentadapters.SimpleRectangularHardcodedGUIComponentAdapter;
15 import net.mograsim.logic.model.serializing.IdentifierGetter;
16 import net.mograsim.logic.model.snippets.HighLevelStateHandler;
17 import net.mograsim.logic.model.snippets.outlinerenderers.DefaultOutlineRenderer;
18 import net.mograsim.logic.model.snippets.symbolrenderers.CenteredTextSymbolRenderer;
19 import net.mograsim.logic.model.snippets.symbolrenderers.CenteredTextSymbolRenderer.CenteredTextParams;
20 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer;
21 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer.PinNamesParams;
22 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer.PinNamesParams.Position;
23
24 public abstract class SimpleRectangularHardcodedGUIComponent extends GUIComponent
25 {
26         private static final double centerTextHeight = 5;
27         private static final double pinNamesHeight = 3.5;
28         private static final double pinNamesMargin = .5;
29
30         private final DefaultOutlineRenderer outlineRenderer;
31         private final CenteredTextSymbolRenderer centerTextRenderer;
32         private final PinNamesSymbolRenderer pinNamesRenderer;
33
34         private AtomicReference<Object> state;
35         private Runnable recalculate;
36
37         // creation and destruction
38
39         public SimpleRectangularHardcodedGUIComponent(ViewModelModifiable model, String name, String centerText)
40         {
41                 super(model, name);
42                 this.outlineRenderer = new DefaultOutlineRenderer(this);
43                 CenteredTextParams centeredTextParams = new CenteredTextParams();
44                 centeredTextParams.text = centerText;
45                 centeredTextParams.fontHeight = centerTextHeight;
46                 this.centerTextRenderer = new CenteredTextSymbolRenderer(this, centeredTextParams);
47                 PinNamesParams pinNamesParams = new PinNamesParams();
48                 pinNamesParams.pinLabelHeight = pinNamesHeight;
49                 pinNamesParams.pinLabelMargin = pinNamesMargin;
50                 this.pinNamesRenderer = new PinNamesSymbolRenderer(this, pinNamesParams);
51                 addPinRemovedListener(this::pinRemoved);
52                 setHighLevelStateHandler(new HighLevelStateHandler()
53                 {
54                         @Override
55                         public Object getParamsForSerializing(IdentifierGetter idGetter)
56                         {
57                                 return null;
58                         }
59
60                         @Override
61                         public Object getHighLevelState(String stateID)
62                         {
63                                 return SimpleRectangularHardcodedGUIComponent.this.getHighLevelState(state.get(), stateID);
64                         }
65
66                         @Override
67                         public void setHighLevelState(String stateID, Object newState)
68                         {
69                                 state.updateAndGet(s -> SimpleRectangularHardcodedGUIComponent.this.setHighLevelState(s, stateID, newState));
70                                 recalculate.run();
71                         }
72                 });
73         }
74
75         // pins
76
77         protected void addPin(Pin pin, Position namePosition)
78         {
79                 super.addPin(pin); // do this first to catch errors
80                 pinNamesRenderer.setPinPosition(pin, namePosition);
81         }
82
83         private void pinRemoved(Pin pin)
84         {
85                 pinNamesRenderer.setPinPosition(pin, null);
86         }
87
88         // high-level access
89
90         @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden
91         protected Object getHighLevelState(Object state, String stateID)
92         {
93                 throw new IllegalArgumentException("No high level state with ID " + stateID);
94         }
95
96         @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden
97         protected Object setHighLevelState(Object lastState, String stateID, Object newHighLevelState)
98         {
99                 throw new IllegalArgumentException("No high level state with ID " + stateID);
100         }
101
102         // logic
103
104         public abstract Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds);
105
106         // logic model binding
107
108         public void setLogicModelBindingAndResetState(AtomicReference<Object> state, Runnable recalculate)
109         {
110                 this.state = state;
111                 this.recalculate = recalculate;
112         }
113
114         // "graphical" operations
115
116         @Override
117         public void render(GeneralGC gc, Rectangle visibleRegion)
118         {
119                 outlineRenderer.render(gc, visibleRegion);
120                 centerTextRenderer.render(gc, visibleRegion);
121                 pinNamesRenderer.render(gc, visibleRegion);
122         }
123
124         // operations no longer supported
125
126         @Override
127         protected void addPin(Pin pin)
128         {
129                 throw new UnsupportedOperationException("Can't add pins without setting usage, call addPin(Pin [, Position]) instead");
130         }
131
132         static
133         {
134                 ViewLogicModelAdapter.addComponentAdapter(new SimpleRectangularHardcodedGUIComponentAdapter());
135         }
136 }