1 package net.mograsim.logic.ui.model.components;
3 import java.io.IOException;
4 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException;
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 import net.mograsim.logic.ui.model.wires.WireCrossPoint;
18 * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
20 public final class GUICustomComponentCreator
22 private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
25 * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
26 * SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
27 * {@link SubmodelComponentParams} describe.
29 * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent}
30 * @return A new SubmodelComponent, as described in the file located at the given path
32 public static SubmodelComponent create(ViewModelModifiable model, String path)
36 SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
37 SubmodelComponent ret = create(model, params, path);
42 System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
45 return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
49 * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent can also be
50 * e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the {@link SubmodelComponentParams} describe.
52 * @param params The parameters describing the {@link SubmodelComponent}
53 * @param path This value is used when the new {@link SubmodelComponent} is an inner component to a different SubmodelComponent, which
54 * is being saved to a file; Then, the new {@link SubmodelComponent} is referenced by its given path within the file.
55 * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
57 public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params, String path)
59 SubmodelComponent comp = null;
60 if (rectC.equals(params.type))
62 comp = createRectComponent(model, params);
67 comp = createSubmodelComponent(model, params);
69 comp.identifierDelegate = () -> "file:".concat(path);
70 initInnerComponents(comp, params.composition);
75 private static SimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model, SubmodelComponentParams params)
79 Map<String, Object> m = params.specialized;
80 SimpleRectangularSubmodelComponent rect = new SimpleRectangularSubmodelComponent(model,
81 ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
82 (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
83 rect.setSubmodelScale(params.composition.innerScale);
84 // rect.setSize(params.width, params.height);
86 int inputCount = ((Number) m.get(SimpleRectangularSubmodelComponent.kInCount)).intValue();
87 String[] inputNames = new String[inputCount];
88 for (int i = 0; i < inputCount; i++)
89 inputNames[i] = params.interfacePins[i].name;
90 rect.setInputPins(inputNames);
92 int outputCount = ((Number) m.get(SimpleRectangularSubmodelComponent.kOutCount)).intValue();
93 String[] outputPins = new String[outputCount];
94 for (int i = 0; i < outputCount; i++)
95 outputPins[i] = params.interfacePins[inputCount + i].name;
96 rect.setOutputPins(outputPins);
100 catch (ClassCastException | NullPointerException e)
102 System.err.println("Failed to specialize component!");
108 private static SubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
110 // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
111 SubmodelComponent comp = new SimpleRectangularSubmodelComponent(model, 0, "");
112 comp.setSubmodelScale(params.composition.innerScale);
113 comp.setSize(params.width, params.height);
114 for (InterfacePinParams iPinParams : params.interfacePins)
116 comp.addSubmodelInterface(
117 new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y));
122 @SuppressWarnings("unused")
123 private static void initInnerComponents(SubmodelComponent comp, ComponentCompositionParams params)
127 GUIComponent[] components = new GUIComponent[params.subComps.length];
128 for (int i = 0; i < components.length; i++)
130 InnerComponentParams cParams = params.subComps[i];
131 String path = cParams.type;
132 if (path.startsWith("class:"))
134 path = path.substring(6);
135 components[i] = createInnerComponentFromClass(comp, path, cParams.params);
136 components[i].moveTo(cParams.pos.x, cParams.pos.y);
137 } else if (path.startsWith("file:"))
139 path = path.substring(5);
140 components[i] = create(comp.submodelModifiable, path);
141 components[i].moveTo(cParams.pos.x, cParams.pos.y);
143 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
146 for (int i = 0; i < params.innerWires.length; i++)
148 InnerWireParams innerWire = params.innerWires[i];
149 new GUIWire(comp.submodelModifiable,
150 comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPin(innerWire.pin1.pinName),
151 comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPin(innerWire.pin2.pinName), innerWire.path);
154 catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException
155 | ClassNotFoundException | IllegalArgumentException e)
157 System.err.println("Failed to initialize custom component!");
162 private static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, String classname, Map<String, Object> params)
163 throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
164 ClassNotFoundException
166 Class<?> c = Class.forName(classname);
168 if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
170 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
171 comp = constructor.newInstance(parent.submodelModifiable,
172 ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
175 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
176 comp = constructor.newInstance(parent.submodelModifiable);
178 return (GUIComponent) comp;