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;
16 * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
18 public final class GUICustomComponentCreator
20 private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
23 * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
24 * SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
25 * {@link SubmodelComponentParams} describe.
27 * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent}
28 * @return A new SubmodelComponent, as described in the file located at the given path
30 public static SubmodelComponent create(ViewModelModifiable model, String path)
34 SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
35 SubmodelComponent ret = create(model, params, path);
40 System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
43 return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
47 * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent can also be
48 * e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the {@link SubmodelComponentParams} describe.
50 * @param params The parameters describing the {@link SubmodelComponent}
51 * @param path This value is used when the new {@link SubmodelComponent} is an inner component to a different SubmodelComponent, which
52 * is being saved to a file; Then, the new {@link SubmodelComponent} is referenced by its given path within the file.
53 * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
55 public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params, String path)
57 SubmodelComponent comp = null;
58 if (rectC.equals(params.type))
60 comp = createRectComponent(model, params);
65 comp = createSubmodelComponent(model, params);
67 comp.identifierDelegate = () -> "file:".concat(path);
68 initInnerComponents(comp, params.composition);
73 private static SimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model, SubmodelComponentParams params)
77 Map<String, Object> m = params.specialized;
78 SimpleRectangularSubmodelComponent rect = new SimpleRectangularSubmodelComponent(model,
79 ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
80 (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
81 rect.setSubmodelScale(params.composition.innerScale);
82 rect.setSize(params.width, params.height);
83 rect.setInputCount(((Number) m.get(SimpleRectangularSubmodelComponent.kInCount)).intValue());
84 rect.setOutputCount(((Number) m.get(SimpleRectangularSubmodelComponent.kOutCount)).intValue());
87 catch (ClassCastException | NullPointerException e)
89 System.err.println("Failed to specialize component!");
95 private static SubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
97 // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
98 SubmodelComponent comp = new SimpleRectangularSubmodelComponent(model, 0, "");
99 comp.setSubmodelScale(params.composition.innerScale);
100 comp.setSize(params.width, params.height);
101 for (InterfacePinParams iPinParams : params.interfacePins)
103 comp.addSubmodelInterface(iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y);
108 @SuppressWarnings("unused")
109 private static void initInnerComponents(SubmodelComponent comp, ComponentCompositionParams params)
113 GUIComponent[] components = new GUIComponent[params.subComps.length];
114 for (int i = 0; i < components.length; i++)
116 InnerComponentParams cParams = params.subComps[i];
117 String path = cParams.type;
118 if (path.startsWith("class:"))
120 path = path.substring(6);
121 components[i] = createInnerComponentFromClass(comp, path, cParams.logicWidth);
122 components[i].moveTo(cParams.pos.x, cParams.pos.y);
123 } else if (path.startsWith("file:"))
125 path = path.substring(5);
126 components[i] = create(comp.submodelModifiable, path);
127 components[i].moveTo(cParams.pos.x, cParams.pos.y);
129 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
132 for (int i = 0; i < params.innerWires.length; i++)
134 InnerWireParams innerWire = params.innerWires[i];
135 new GUIWire(comp.submodelModifiable,
136 comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPins().get(innerWire.pin1.pinIndex),
137 comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPins().get(innerWire.pin2.pinIndex),
141 catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException
142 | ClassNotFoundException | IllegalArgumentException e)
144 System.err.println("Failed to initialize custom component!");
149 private static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, String classname, int logicWidth)
150 throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
151 NoSuchMethodException, SecurityException, ClassNotFoundException
153 Class<?> c = Class.forName(classname);
157 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
158 comp = constructor.newInstance(parent.submodelModifiable);
160 catch (@SuppressWarnings("unused") NoSuchMethodException e)
162 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
163 comp = constructor.newInstance(parent.submodelModifiable, logicWidth);
166 if (comp instanceof GUIComponent)
167 return (GUIComponent) comp;
168 throw new IllegalArgumentException("Class given as subcomponent was not a GUIComponent!");