Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / atomic / ModelClock.java
1 package net.mograsim.logic.model.model.components.atomic;
2
3 import org.eclipse.swt.graphics.Color;
4
5 import com.google.gson.JsonSyntaxException;
6
7 import net.haspamelodica.swt.helper.gcs.GeneralGC;
8 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
9 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
10 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
11 import net.mograsim.logic.core.LogicObserver;
12 import net.mograsim.logic.core.components.CoreClock;
13 import net.mograsim.logic.model.model.LogicModelModifiable;
14 import net.mograsim.logic.model.model.components.ModelComponent;
15 import net.mograsim.logic.model.model.components.Orientation;
16 import net.mograsim.logic.model.model.components.OrientationCalculator;
17 import net.mograsim.logic.model.model.wires.Pin;
18 import net.mograsim.logic.model.model.wires.PinUsage;
19 import net.mograsim.logic.model.modeladapter.LogicCoreAdapter;
20 import net.mograsim.logic.model.modeladapter.componentadapters.ClockAdapter;
21 import net.mograsim.logic.model.serializing.IdentifyParams;
22 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
23 import net.mograsim.logic.model.util.JsonHandler;
24 import net.mograsim.preferences.Preferences;
25
26 public class ModelClock extends ModelComponent
27 {
28         private static final double width = 20;
29         private static final double height = 20;
30         private static final double fontHeight = 5;
31
32         private final Pin outputPin;
33
34         private final LogicObserver logicObs;
35         private ModelClockParams params;
36         private OrientationCalculator oc;
37         private CoreClock clock;
38
39         public ModelClock(LogicModelModifiable model, ModelClockParams params)
40         {
41                 this(model, params, null);
42         }
43
44         public ModelClock(LogicModelModifiable model, ModelClockParams params, String name)
45         {
46                 super(model, name, false);
47                 this.params = params;
48                 logicObs = (i) -> model.requestRedraw();
49
50                 oc = new OrientationCalculator(params.orientation, width, height);
51                 setSize(oc.width(), oc.height());
52
53                 this.outputPin = new Pin(model, this, "", 1, PinUsage.OUTPUT, oc.newX(width, height / 2), oc.newY(width, height / 2));
54                 addPin(outputPin);
55
56                 init();
57         }
58
59         @Override
60         public void render(GeneralGC gc, Rectangle visibleRegion)
61         {
62                 Color foreground = Preferences.current().getColor("net.mograsim.logic.model.color.foreground");
63                 if (foreground != null)
64                         gc.setForeground(foreground);
65                 gc.drawRectangle(getBounds());
66                 String label = clock == null ? "null" : (clock.isOn() ? "|" : "\u2015");
67                 Font oldFont = gc.getFont();
68                 Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
69                 gc.setFont(labelFont);
70                 Point textExtent = gc.textExtent(label);
71                 Color textColor = Preferences.current().getColor("net.mograsim.logic.model.color.text");
72                 if (textColor != null)
73                         gc.setForeground(textColor);
74                 gc.drawText(label, getPosX() + (oc.width() - textExtent.x) / 2, getPosY() + (oc.height() - textExtent.y) / 2, true);
75                 gc.setFont(oldFont);
76         }
77
78         public void setCoreModelBinding(CoreClock clock)
79         {
80                 if (this.clock != null)
81                         this.clock.deregisterObserver(logicObs);
82                 this.clock = clock;
83                 if (clock != null)
84                         clock.registerObserver(logicObs);
85         }
86
87         public boolean hasCoreModelBinding()
88         {
89                 return clock != null;
90         }
91
92         @Override
93         public Object getHighLevelState(String stateID)
94         {
95                 switch (stateID)
96                 {
97                 case "out":
98                         if (clock != null)
99                                 return clock.getOut().getInputValues();
100                         return null;
101                 default:
102                         return super.getHighLevelState(stateID);
103                 }
104         }
105
106         @Override
107         public void setHighLevelState(String stateID, Object newState)
108         {
109                 switch (stateID)
110                 {
111                 case "out":
112                         throw new UnsupportedOperationException("cannot set state of clock");
113                 default:
114                         super.setHighLevelState(stateID, newState);
115                 }
116         }
117
118         public CoreClock getClock()
119         {
120                 return clock;
121         }
122
123         public Pin getOutputPin()
124         {
125                 return outputPin;
126         }
127
128         public int getDelta()
129         {
130                 return params.delta;
131         }
132
133         @Override
134         public String getIDForSerializing(IdentifyParams idParams)
135         {
136                 return "Clock";
137         }
138
139         @Override
140         public ModelClockParams getParamsForSerializing(IdentifyParams idParams)
141         {
142                 return params;
143         }
144
145         static
146         {
147                 LogicCoreAdapter.addComponentAdapter(new ClockAdapter());
148                 IndirectModelComponentCreator.setComponentSupplier(ModelClock.class.getName(), (m, p, n) ->
149                 {
150                         ModelClockParams params = JsonHandler.fromJsonTree(p, ModelClockParams.class);
151                         if (params == null)
152                                 throw new JsonSyntaxException("Invalid!!!");
153                         return new ModelClock(m, params, n);
154                 });
155         }
156
157         public static class ModelClockParams
158         {
159                 int delta;
160                 Orientation orientation;
161
162                 public ModelClockParams(int delta, Orientation orientation)
163                 {
164                         this.delta = delta;
165                         this.orientation = orientation;
166                 }
167         }
168 }