From: Fabian Stemmler Date: Mon, 10 Jun 2019 20:07:36 +0000 (+0200) Subject: Added file representation for SimpleRectangularSubmodelComponents X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;ds=inline;h=ddb921f849b4393fd01e70de4447865d09bb9daa;p=Mograsim.git Added file representation for SimpleRectangularSubmodelComponents SimpleRectangularSubmodelComponents can now be saved into a .json file (via ComponentParams writeJSON method) GUICustomComponents can now be created from a .json file This system does not yet support general SubmodelComponents and thus the format is still subject to change. --- diff --git a/net.mograsim.logic.ui/META-INF/MANIFEST.MF b/net.mograsim.logic.ui/META-INF/MANIFEST.MF index 24a1c9a2..3bfa20ac 100644 --- a/net.mograsim.logic.ui/META-INF/MANIFEST.MF +++ b/net.mograsim.logic.ui/META-INF/MANIFEST.MF @@ -13,5 +13,6 @@ Export-Package: net.mograsim.logic.ui, Bundle-RequiredExecutionEnvironment: JavaSE-10 Require-Bundle: org.eclipse.swt;bundle-version="3.110.0", SWTZoomableCanvas;bundle-version="1.0.0";visibility:=reexport, - net.mograsim.logic.core;bundle-version="1.0.0";visibility:=reexport + net.mograsim.logic.core;bundle-version="1.0.0";visibility:=reexport, + com.google.gson;bundle-version="2.8.2" Automatic-Module-Name: net.mograsim.logic.ui diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java new file mode 100644 index 00000000..1a273bd8 --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java @@ -0,0 +1,56 @@ +package net.mograsim.logic.ui.model.components; + +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; + +public class ComponentParams +{ + private static Gson parser = new GsonBuilder().setPrettyPrinting().create(); + String displayName; + int inputCount, outputCount, logicWidth; + double innerScale; + + InnerComponentParams[] subComps; + InnerWireParams[] innerWires; + + public static class InnerComponentParams + { + Point pos; + String type; + int logicWidth; + } + + public static class InnerWireParams + { + InnerPinParams pin1, pin2; + Point[] path; + } + + public static class InnerPinParams + { + int compId, pinIndex; + } + + @SuppressWarnings("resource") + public static ComponentParams readJSON(String path) throws IOException + { + FileReader reader = new FileReader(path); + ComponentParams params = parser.fromJson(new FileReader(path), ComponentParams.class); + reader.close(); + return params; + } + + public void writeJSON(String path) throws IOException + { + @SuppressWarnings("resource") + FileWriter writer = new FileWriter(path); + writer.write(parser.toJson(this)); + writer.close(); + } +} diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java new file mode 100644 index 00000000..6f84daf5 --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java @@ -0,0 +1,111 @@ +package net.mograsim.logic.ui.model.components; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import net.mograsim.logic.ui.model.ViewModelModifiable; +import net.mograsim.logic.ui.model.components.ComponentParams.InnerComponentParams; +import net.mograsim.logic.ui.model.components.ComponentParams.InnerWireParams; +import net.mograsim.logic.ui.model.wires.GUIWire; + +public class GUICustomComponent extends SimpleRectangularSubmodelComponent +{ + private String path = "NONE"; + + public static GUICustomComponent create(ViewModelModifiable model, String path) + { + try + { + ComponentParams params = ComponentParams.readJSON(path); + return create(model, params); + } + catch (IOException e) + { + System.err.println(String.format("Failed to create custom component from invalid path: %s", path)); + e.printStackTrace(); + } + return new GUICustomComponent(model, 0, "ERROR"); + } + + public static GUICustomComponent create(ViewModelModifiable model, ComponentParams params) + { + GUICustomComponent comp = new GUICustomComponent(model, params.logicWidth, params.displayName); + comp.setSubmodelScale(params.innerScale); + comp.setInputCount(params.inputCount); + comp.setOutputCount(params.outputCount); + comp.initSubmodelComponents(params); + return comp; + } + + private GUICustomComponent(ViewModelModifiable model, int logicWidth, String displayName) + { + super(model, logicWidth, displayName); + } + + @SuppressWarnings("unused") + private void initSubmodelComponents(ComponentParams params) + { + try + { + GUIComponent[] components = new GUIComponent[params.subComps.length]; + for (int i = 0; i < components.length; i++) + { + InnerComponentParams cParams = params.subComps[i]; + String path = cParams.type; + if (path.startsWith("class:")) + { + path = path.substring(6); + components[i] = createComponent(path, cParams.logicWidth); + components[i].moveTo(cParams.pos.x, cParams.pos.y); + } else if (path.startsWith("file:")) + { + path = path.substring(5); + components[i] = create(submodelModifiable, path); + components[i].moveTo(cParams.pos.x, cParams.pos.y); + } else + throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'"); + } + + for (int i = 0; i < params.innerWires.length; i++) + { + InnerWireParams innerWire = params.innerWires[i]; + new GUIWire(submodelModifiable, + submodelModifiable.getComponents().get(innerWire.pin1.compId).getPins().get(innerWire.pin1.pinIndex), + submodelModifiable.getComponents().get(innerWire.pin2.compId).getPins().get(innerWire.pin2.pinIndex), + innerWire.path); + } + } + catch (Exception e) + { + System.err.println("Failed to create custom component!"); + e.printStackTrace(); + } + } + + private GUIComponent createComponent(String classname, int logicWidth) throws InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException + { + Class c = Class.forName(classname); + Object comp; + try + { + Constructor constructor = c.getConstructor(ViewModelModifiable.class); + comp = constructor.newInstance(submodelModifiable); + } + catch (@SuppressWarnings("unused") NoSuchMethodException e) + { + Constructor constructor = c.getConstructor(ViewModelModifiable.class, int.class); + comp = constructor.newInstance(submodelModifiable, logicWidth); + } + + if (comp instanceof GUIComponent) + return (GUIComponent) comp; + throw new IllegalArgumentException("Class given as subcomponent was not a GUIComponent!"); + } + + public String getPath() + { + return path; + } +} diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SimpleRectangularSubmodelComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SimpleRectangularSubmodelComponent.java index 89a55f01..f537eec2 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SimpleRectangularSubmodelComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SimpleRectangularSubmodelComponent.java @@ -2,6 +2,7 @@ package net.mograsim.logic.ui.model.components; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import net.haspamelodica.swt.helper.gcs.GeneralGC; @@ -9,6 +10,10 @@ import net.haspamelodica.swt.helper.swtobjectwrappers.Font; import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.ui.model.ViewModelModifiable; +import net.mograsim.logic.ui.model.components.ComponentParams.InnerComponentParams; +import net.mograsim.logic.ui.model.components.ComponentParams.InnerPinParams; +import net.mograsim.logic.ui.model.components.ComponentParams.InnerWireParams; +import net.mograsim.logic.ui.model.wires.GUIWire; import net.mograsim.logic.ui.model.wires.Pin; public class SimpleRectangularSubmodelComponent extends SubmodelComponent @@ -122,4 +127,56 @@ public class SimpleRectangularSubmodelComponent extends SubmodelComponent { gc.drawRectangle(getBounds()); } + + public ComponentParams calculateParams() + { + ComponentParams params = new ComponentParams(); + params.displayName = label; + params.inputCount = inputSupermodelPins.size(); + params.outputCount = outputSubmodelPins.size(); + params.logicWidth = logicWidth; + params.innerScale = getSubmodelScale(); + + List compList = submodelModifiable.getComponents(); + Iterator componentIt = compList.iterator(); + componentIt.next(); // Skip inner SubmodelInterface + InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1]; + int i = 0; + while (componentIt.hasNext()) + { + GUIComponent component = componentIt.next(); + InnerComponentParams inner = new InnerComponentParams(); + comps[i] = inner; + inner.logicWidth = component.getPins().get(0).logicWidth; // This could be done a little more elegantly + Rectangle bounds = component.getBounds(); + inner.pos = new Point(bounds.x, bounds.y); + if (component instanceof GUICustomComponent) + inner.type = "file:" + ((GUICustomComponent) component).getPath(); + else + inner.type = "class:" + component.getClass().getCanonicalName(); + i++; + } + params.subComps = comps; + + List wireList = submodelModifiable.getWires(); + InnerWireParams wires[] = new InnerWireParams[wireList.size()]; + i = 0; + for (GUIWire wire : wireList) + { + InnerWireParams inner = new InnerWireParams(); + wires[i] = inner; + InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams(); + + pin1Params.pinIndex = wire.getPin1().component.getPins().indexOf(wire.getPin1()); + pin1Params.compId = compList.indexOf(wire.getPin1().component); + pin2Params.pinIndex = wire.getPin2().component.getPins().indexOf(wire.getPin2()); + pin2Params.compId = compList.indexOf(wire.getPin2().component); + inner.pin1 = pin1Params; + inner.pin2 = pin2Params; + inner.path = wire.getPath(); + i++; + } + params.innerWires = wires; + return params; + } } \ No newline at end of file diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java index a4fe1aa4..43ec22b0 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java @@ -58,6 +58,11 @@ public abstract class SubmodelComponent extends GUIComponent requestRedraw();// needed if there is no submodel interface pin } + protected double getSubmodelScale() + { + return submodelScale; + } + /** * Returns the submodel pin. */ diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java index 47f85171..eb7e8aba 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java @@ -185,6 +185,11 @@ public class GUIWire return pin2; } + public Point[] getPath() + { + return path == null ? null : path.clone(); + } + // @formatter:off public void addRedrawListener (Runnable listener) {redrawListeners .add (listener);}