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;
7 import net.mograsim.logic.ui.model.ViewModelModifiable;
8 import net.mograsim.logic.ui.model.components.params.GeneralComponentParams;
9 import net.mograsim.logic.ui.model.components.params.RectComponentParams;
10 import net.mograsim.logic.ui.model.components.params.SubComponentParams;
11 import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerComponentParams;
12 import net.mograsim.logic.ui.model.components.params.RectComponentParams.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 class CustomRectComponent extends SimpleRectangularSubmodelComponent
22 protected CustomRectComponent(ViewModelModifiable model, int logicWidth, String label, String path)
24 super(model, logicWidth, label);
29 public String getIdentifier()
31 return "file:".concat(path);
35 public static SubmodelComponent create(ViewModelModifiable model, String path)
39 if (path.endsWith(RectComponentParams.fileExtension))
41 RectComponentParams params = RectComponentParams.readJson(path);
42 SubmodelComponent ret = create(model, params, path);
44 } else if (path.endsWith(SubComponentParams.fileExtension))
46 SubComponentParams params = SubComponentParams.readJson(path);
47 SubmodelComponent ret = create(model, params, path);
50 throw new IOException(String.format("\"%s\" does not have a valid file extension. Must be either %s or %s", path,
51 RectComponentParams.fileExtension, SubComponentParams.fileExtension));
55 System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
58 return new CustomRectComponent(model, 0, "ERROR", "NONE");
62 * @param path This value is used when the new SubmodelComponent is an inner component to a different SubmodelComponent, which is being
63 * saved to a file; Then, the new SubmodelComponent is referenced by its given path within the file.
65 public static SimpleRectangularSubmodelComponent create(ViewModelModifiable model, RectComponentParams params, String path)
67 CustomRectComponent comp = new CustomRectComponent(model, params.logicWidth, params.displayName, path);
68 comp.setSubmodelScale(params.composition.innerScale);
69 comp.setInputCount(params.inputCount);
70 comp.setOutputCount(params.outputCount);
71 initSubmodelComponents(comp, params.composition);
76 * @param path This value is used when the new SubmodelComponent is an inner component to a different SubmodelComponent, which is being
77 * saved to a file; Then, the new SubmodelComponent is referenced by its given path within the file.
79 public static SubmodelComponent create(ViewModelModifiable model, SubComponentParams params, String path)
81 // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
82 CustomRectComponent comp = new CustomRectComponent(model, 0, "", path);
83 comp.setSubmodelScale(params.composition.innerScale);
84 comp.setSize(params.width, params.height);
85 for (InterfacePinParams iPinParams : params.interfacePins)
87 comp.addSubmodelInterface(iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y);
89 initSubmodelComponents(comp, params.composition);
93 @SuppressWarnings("unused")
94 private static void initSubmodelComponents(SubmodelComponent comp, GeneralComponentParams params)
98 GUIComponent[] components = new GUIComponent[params.subComps.length];
99 for (int i = 0; i < components.length; i++)
101 InnerComponentParams cParams = params.subComps[i];
102 String path = cParams.type;
103 if (path.startsWith("class:"))
105 path = path.substring(6);
106 components[i] = createInnerComponentFromClass(comp, path, cParams.logicWidth);
107 components[i].moveTo(cParams.pos.x, cParams.pos.y);
108 } else if (path.startsWith("file:"))
110 path = path.substring(5);
111 components[i] = create(comp.submodelModifiable, path);
112 components[i].moveTo(cParams.pos.x, cParams.pos.y);
114 throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
117 for (int i = 0; i < params.innerWires.length; i++)
119 InnerWireParams innerWire = params.innerWires[i];
120 new GUIWire(comp.submodelModifiable,
121 comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPins().get(innerWire.pin1.pinIndex),
122 comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPins().get(innerWire.pin2.pinIndex),
128 System.err.println("Failed to create custom component!");
133 private static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, String classname, int logicWidth)
134 throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
135 NoSuchMethodException, SecurityException, ClassNotFoundException
137 Class<?> c = Class.forName(classname);
141 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
142 comp = constructor.newInstance(parent.submodelModifiable);
144 catch (@SuppressWarnings("unused") NoSuchMethodException e)
146 Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
147 comp = constructor.newInstance(parent.submodelModifiable, logicWidth);
150 if (comp instanceof GUIComponent)
151 return (GUIComponent) comp;
152 throw new IllegalArgumentException("Class given as subcomponent was not a GUIComponent!");