Serializing now serializes everything; among many other things:
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / submodels / SimpleRectangularSubmodelComponent.java
1 package net.mograsim.logic.model.model.components.submodels;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashSet;
7 import java.util.List;
8
9 import net.mograsim.logic.model.model.ViewModelModifiable;
10 import net.mograsim.logic.model.model.wires.MovablePin;
11 import net.mograsim.logic.model.model.wires.Pin;
12 import net.mograsim.logic.model.snippets.outlinerenderers.DefaultOutlineRenderer;
13 import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer;
14 import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams;
15
16 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
17 {
18         public static final double width = 35;
19         public static final double pinDistance = 10;
20         public static final double pinNameMargin = .5;
21         public static final double labelFontHeight = 5;
22         public static final double pinNameFontHeight = 3.5;
23
24         public final String label;
25         protected final int logicWidth;
26
27         private final List<String> inputPinNames;
28         private final List<String> inputPinNamesUnmodifiable;
29         private final List<String> outputPinNames;
30         private final List<String> outputPinNamesUnmodifiable;
31
32         public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
33         {
34                 this(model, logicWidth, label, null);
35         }
36
37         public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label, String name)
38         {
39                 super(model, name);
40                 this.label = label;
41                 this.logicWidth = logicWidth;
42                 this.inputPinNames = new ArrayList<>();
43                 this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
44                 this.outputPinNames = new ArrayList<>();
45                 this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
46
47                 SimpleRectangularLikeParams rendererParams = new SimpleRectangularLikeParams();
48                 rendererParams.centerText = label;
49                 rendererParams.centerTextHeight = labelFontHeight;
50                 rendererParams.horizontalComponentCenter = width / 2;
51                 rendererParams.pinLabelHeight = pinNameFontHeight;
52                 rendererParams.pinLabelMargin = pinNameMargin;
53                 setSymbolRenderer(new SimpleRectangularLikeSymbolRenderer(this, rendererParams));
54                 setOutlineRenderer(new DefaultOutlineRenderer(this));
55         }
56
57         protected void setInputPins(String... pinNames)
58         {
59                 setIOPins(0, inputPinNames, outputPinNames, pinNames);
60         }
61
62         protected void setOutputPins(String... pinNames)
63         {
64                 setIOPins(width, outputPinNames, inputPinNames, pinNames);
65         }
66
67         private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
68         {
69                 int inputCount = newPinNames.length;
70                 List<String> newPinNamesList = Arrays.asList(newPinNames);
71                 if (new HashSet<>(newPinNamesList).size() != inputCount)
72                         throw new IllegalArgumentException("Pin names contain duplicates");
73                 for (String pinName : newPinNamesList)
74                         if (pinNamesListOtherSide.contains(pinName))
75                                 throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
76                 super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
77                 for (int i = 0; i < inputCount; i++)
78                 {
79                         String pinName = newPinNames[i];
80                         int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
81                         if (oldPinIndex == -1)
82                                 super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
83                         else
84                                 getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
85                 }
86                 for (String pinName : pinNamesListThisSide)
87                         if (!newPinNamesList.contains(pinName))
88                                 super.removeSubmodelInterface(pinName);
89                 pinNamesListThisSide.clear();
90                 pinNamesListThisSide.addAll(newPinNamesList);
91         }
92
93         public List<String> getInputPinNames()
94         {
95                 return inputPinNamesUnmodifiable;
96         }
97
98         public List<String> getOutputPinNames()
99         {
100                 return outputPinNamesUnmodifiable;
101         }
102
103         @Override
104         protected Pin addSubmodelInterface(MovablePin supermodelPin)
105         {
106                 throw new UnsupportedOperationException(
107                                 "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
108         }
109
110         @Override
111         protected void removeSubmodelInterface(String name)
112         {
113                 throw new UnsupportedOperationException(
114                                 "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
115         }
116
117         @Override
118         protected void setSize(double width, double height)
119         {
120                 throw new UnsupportedOperationException(
121                                 "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
122         }
123 }