Added MSB first versions of parse() and toString()
[Mograsim.git] / net.mograsim.logic.ui / src / net / mograsim / logic / ui / model / components / GUICustomComponentCreator.java
1 package net.mograsim.logic.ui.model.components;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Map;
7
8 import net.mograsim.logic.ui.model.ViewModelModifiable;
9 import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams;
10 import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
11 import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerWireParams;
12 import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InterfacePinParams;
13 import net.mograsim.logic.ui.model.wires.GUIWire;
14 import net.mograsim.logic.ui.model.wires.MovablePin;
15
16 /**
17  * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
18  */
19 public final class GUICustomComponentCreator
20 {
21         private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
22
23         /**
24          * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
25          * SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
26          * {@link SubmodelComponentParams} describe.
27          * 
28          * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent}
29          * @return A new SubmodelComponent, as described in the file located at the given path
30          */
31         public static SubmodelComponent create(ViewModelModifiable model, String path)
32         {
33                 try
34                 {
35                         SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
36                         SubmodelComponent ret = create(model, params);
37                         return ret;
38                 }
39                 catch (IOException e)
40                 {
41                         System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
42                         e.printStackTrace();
43                 }
44                 return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
45         }
46
47         /**
48          * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent can also be
49          * e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the {@link SubmodelComponentParams} describe.
50          * 
51          * @param params The parameters describing the {@link SubmodelComponent}
52          * 
53          * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
54          */
55         public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params)
56         {
57                 SubmodelComponent comp = null;
58                 if (rectC.equals(params.type))
59                 {
60                         comp = createRectComponent(model, params);
61                 }
62
63                 if (comp == null)
64                 {
65                         comp = createSubmodelComponent(model, params);
66                 }
67                 comp.identifierDelegate = () -> params.name;
68                 initInnerComponents(comp, params.composition);
69                 return comp;
70         }
71
72         // May return null
73         @SuppressWarnings("unchecked")
74         private static SimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model, SubmodelComponentParams params)
75         {
76                 try
77                 {
78                         Map<String, Object> m = params.specialized;
79                         SimpleRectangularSubmodelComponent rect = new SimpleRectangularSubmodelComponent(model,
80                                         ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
81                                         (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
82                         rect.setSubmodelScale(params.composition.innerScale);
83
84                         Object[] names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kInCount)).toArray();
85                         rect.setInputPins(Arrays.copyOf(names, names.length, String[].class));
86
87                         names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kOutCount)).toArray();
88                         rect.setOutputPins(Arrays.copyOf(names, names.length, String[].class));
89
90                         return rect;
91                 }
92                 catch (ClassCastException | NullPointerException e)
93                 {
94                         System.err.println("Failed to specialize component!");
95                         e.printStackTrace();
96                         return null;
97                 }
98         }
99
100         private static SubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
101         {
102                 // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
103                 SubmodelComponent comp = new SimpleRectangularSubmodelComponent(model, 0, "");
104                 comp.setSubmodelScale(params.composition.innerScale);
105                 comp.setSize(params.width, params.height);
106                 for (InterfacePinParams iPinParams : params.interfacePins)
107                 {
108                         comp.addSubmodelInterface(
109                                         new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y));
110                 }
111                 return comp;
112         }
113
114         @SuppressWarnings("unused")
115         private static void initInnerComponents(SubmodelComponent comp, ComponentCompositionParams params)
116         {
117                 GUIComponent[] components = new GUIComponent[params.subComps.length];
118                 for (int i = 0; i < components.length; i++)
119                 {
120                         InnerComponentParams cParams = params.subComps[i];
121                         String path = cParams.name;
122                         components[i] = GUIComponentCreator.create(comp.submodelModifiable, cParams.name, cParams.params);
123                         components[i].moveTo(cParams.pos.x, cParams.pos.y);
124                 }
125
126                 for (int i = 0; i < params.innerWires.length; i++)
127                 {
128                         InnerWireParams innerWire = params.innerWires[i];
129                         new GUIWire(comp.submodelModifiable,
130                                         comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPin(innerWire.pin1.pinName),
131                                         comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPin(innerWire.pin2.pinName), innerWire.path);
132                 }
133         }
134 }