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.InnerComponentParams;
10 import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams;
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.WireCrossPoint;
17 * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
19 public final class GUICustomComponentCreator
21 private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
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.
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
31 public static SubmodelComponent create(ViewModelModifiable model, String path)
35 SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
36 SubmodelComponent ret = create(model, params, path);
41 System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
44 return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
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.
51 * @param params The parameters describing the {@link SubmodelComponent}
52 * @param path This value is used when the new {@link SubmodelComponent} is an inner component to a different SubmodelComponent, which
53 * is being saved to a file; Then, the new {@link SubmodelComponent} is referenced by its given path within the file.
54 * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
56 public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params, String path)
58 SubmodelComponent comp = null;
59 if (rectC.equals(params.type))
61 comp = createRectComponent(model, params);
66 comp = createSubmodelComponent(model, params);
68 comp.identifierDelegate = () -> "file:".concat(path);
69 initInnerComponents(comp, params.composition);
74 private static SimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model, SubmodelComponentParams params)
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 // rect.setSize(params.width, params.height);
85 // TODO save & restore names
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(iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y);
121 @SuppressWarnings("unused")
122 private static void initInnerComponents(SubmodelComponent comp, ComponentCompositionParams params)
126 GUIComponent[] components = new GUIComponent[params.subComps.length];
127 for (int i = 0; i < components.length; i++)
129 InnerComponentParams cParams = params.subComps[i];
130 String path = cParams.type;
131 if (path.startsWith("class:"))
133 path = path.substring(6);
134 components[i] = createInnerComponentFromClass(comp, path, cParams.params);
135 components[i].moveTo(cParams.pos.x, cParams.pos.y);
136 } else if (path.startsWith("file:"))
138 path = path.substring(5);
139 components[i] = create(comp.submodelModifiable, path);
140 components[i].moveTo(cParams.pos.x, cParams.pos.y);
142 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
145 for (int i = 0; i < params.innerWires.length; i++)
147 InnerWireParams innerWire = params.innerWires[i];
148 new GUIWire(comp.submodelModifiable,
149 comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPin(innerWire.pin1.pinName),
150 comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPin(innerWire.pin2.pinName), innerWire.path);
153 catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException
154 | ClassNotFoundException | IllegalArgumentException e)
156 System.err.println("Failed to initialize custom component!");
161 private static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, String classname, Map<String, Object> params)
162 throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
163 ClassNotFoundException
165 Class<?> c = Class.forName(classname);
167 if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
169 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
170 comp = constructor.newInstance(parent.submodelModifiable,
171 ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
174 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
175 comp = constructor.newInstance(parent.submodelModifiable);
177 return (GUIComponent) comp;