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.params.GeneralComponentParams;
10 import net.mograsim.logic.ui.model.components.params.GeneralComponentParams.InnerComponentParams;
11 import net.mograsim.logic.ui.model.components.params.SubComponentParams;
12 import net.mograsim.logic.ui.model.components.params.SubComponentParams.InnerWireParams;
13 import net.mograsim.logic.ui.model.components.params.SubComponentParams.InterfacePinParams;
14 import net.mograsim.logic.ui.model.wires.GUIWire;
16 public class GUICustomComponentCreator
18 private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
20 private static class CustomRectComponent extends SimpleRectangularSubmodelComponent
24 protected CustomRectComponent(ViewModelModifiable model, int logicWidth, String label, String path)
26 super(model, logicWidth, label);
31 public String getIdentifier()
33 return "file:".concat(path);
37 public static SubmodelComponent create(ViewModelModifiable model, String path)
41 SubComponentParams params = SubComponentParams.readJson(path);
42 SubmodelComponent ret = create(model, params, path);
47 System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
50 return new CustomRectComponent(model, 0, "ERROR", "NONE");
54 * @param path This value is used when the new SubmodelComponent is an inner component to a different SubmodelComponent, which is being
55 * saved to a file; Then, the new SubmodelComponent is referenced by its given path within the file.
57 public static SubmodelComponent create(ViewModelModifiable model, SubComponentParams params, String path)
59 // TODO: Clean up this mess
60 SubmodelComponent comp = null;
61 if (rectC.equals(params.type))
65 Map<String, Object> m = params.specialized;
66 SimpleRectangularSubmodelComponent rect = new CustomRectComponent(model,
67 ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
68 (String) m.get(SimpleRectangularSubmodelComponent.kLabel), path);
69 rect.setSubmodelScale(params.composition.innerScale);
70 rect.setSize(params.width, params.height);
71 rect.setInputCount(((Number) m.get(SimpleRectangularSubmodelComponent.kInCount)).intValue());
72 rect.setOutputCount(((Number) m.get(SimpleRectangularSubmodelComponent.kOutCount)).intValue());
75 catch (ClassCastException | NullPointerException e)
77 System.err.println("Failed to specialize component!");
83 // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
84 comp = new CustomRectComponent(model, 0, "", path);
86 comp.setSubmodelScale(params.composition.innerScale);
87 comp.setSize(params.width, params.height);
88 for (InterfacePinParams iPinParams : params.interfacePins)
90 comp.addSubmodelInterface(iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y);
93 initSubmodelComponents(comp, params.composition);
97 @SuppressWarnings("unused")
98 private static void initSubmodelComponents(SubmodelComponent comp, GeneralComponentParams params)
102 GUIComponent[] components = new GUIComponent[params.subComps.length];
103 for (int i = 0; i < components.length; i++)
105 InnerComponentParams cParams = params.subComps[i];
106 String path = cParams.type;
107 if (path.startsWith("class:"))
109 path = path.substring(6);
110 components[i] = createInnerComponentFromClass(comp, path, cParams.logicWidth);
111 components[i].moveTo(cParams.pos.x, cParams.pos.y);
112 } else if (path.startsWith("file:"))
114 path = path.substring(5);
115 components[i] = create(comp.submodelModifiable, path);
116 components[i].moveTo(cParams.pos.x, cParams.pos.y);
118 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
121 for (int i = 0; i < params.innerWires.length; i++)
123 InnerWireParams innerWire = params.innerWires[i];
124 new GUIWire(comp.submodelModifiable,
125 comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPins().get(innerWire.pin1.pinIndex),
126 comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPins().get(innerWire.pin2.pinIndex),
132 System.err.println("Failed to create custom component!");
137 private static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, String classname, int logicWidth)
138 throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
139 NoSuchMethodException, SecurityException, ClassNotFoundException
141 Class<?> c = Class.forName(classname);
145 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
146 comp = constructor.newInstance(parent.submodelModifiable);
148 catch (@SuppressWarnings("unused") NoSuchMethodException e)
150 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
151 comp = constructor.newInstance(parent.submodelModifiable, logicWidth);
154 if (comp instanceof GUIComponent)
155 return (GUIComponent) comp;
156 throw new IllegalArgumentException("Class given as subcomponent was not a GUIComponent!");