General SubmodelComponents can now be saved to a json format
authorFabian Stemmler <stemmler@in.tum.de>
Fri, 14 Jun 2019 13:40:57 +0000 (15:40 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Fri, 14 Jun 2019 13:40:57 +0000 (15:40 +0200)
Format for SimpleRectangularSubmodelComponents has changed.
Format for SubmodelComponents holds information on Pin positions.
Both SubmodelComponents and SimpleRect... can be created through the
GUICustomComponentCreator (SubmodelComponents are created as
SimpleRect..., as SubmodelComponent is abstract). This can be expanded
upon for the addition of more subclasses to SubmodelComponent. Included
a class JsonExample for testing a few standard cases.

net.mograsim.logic.ui/src/net/mograsim/logic/ui/examples/JsonExample.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java [deleted file]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java [deleted file]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponentCreator.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SimpleRectangularSubmodelComponent.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/GeneralComponentParams.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/JsonHandler.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/RectComponentParams.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/SubComponentParams.java [new file with mode: 0644]

diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/examples/JsonExample.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/examples/JsonExample.java
new file mode 100644 (file)
index 0000000..c6a2e7b
--- /dev/null
@@ -0,0 +1,146 @@
+package net.mograsim.logic.ui.examples;
+
+import java.io.IOException;
+
+import net.mograsim.logic.ui.SimpleLogicUIStandalone;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.components.GUICustomComponentCreator;
+import net.mograsim.logic.ui.model.components.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.SubmodelComponent;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUIand;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUIfulladder;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUIhalfadder;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUImux1;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUImux1_4;
+import net.mograsim.logic.ui.model.components.mi.nandbased.GUIsel2_4;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams;
+import net.mograsim.logic.ui.model.components.params.SubComponentParams;
+import net.mograsim.logic.ui.model.wires.GUIWire;
+
+public class JsonExample
+{
+       public static void main(String[] args)
+       {
+               SimpleLogicUIStandalone.executeVisualisation(JsonExample::createFromJsonExample);
+       }
+
+       private static class TestComponent extends SimpleRectangularSubmodelComponent
+       {
+               protected TestComponent(ViewModelModifiable model)
+               {
+                       super(model, 1, "Test");
+                       setInputCount(1);
+                       setSubmodelScale(.4);
+                       GUICustomComponentCreator.create(submodelModifiable, "HalfAdder.rc");
+               }
+       }
+
+       // Execute only after HalfAdder.rc has been created
+       public static void refJsonFromJsonTest(ViewModelModifiable model)
+       {
+               TestComponent t = new TestComponent(model);
+               t.calculateParams().writeJson("Test.sc");
+               SubmodelComponent c = GUICustomComponentCreator.create(model, "Test.sc");
+               c.moveTo(0, 50);
+
+       }
+
+       public static void createHalfAdderExample(ViewModelModifiable model)
+       {
+               GUIhalfadder tmp = new GUIhalfadder(model);
+               tmp.moveTo(1000, 50);
+               RectComponentParams p = tmp.calculateRectParams();
+               SubComponentParams pC = tmp.calculateParams();
+               try
+               {
+                       p.writeJson("HalfAdder.rc");
+                       pC.writeJson("HalfAdder.sc");
+                       p = RectComponentParams.readJson("HalfAdder.rc");
+                       pC = SubComponentParams.readJson("HalfAdder.sc");
+               }
+               catch (IOException e)
+               {
+                       e.printStackTrace();
+               }
+
+               SubmodelComponent adder = GUICustomComponentCreator.create(model, p, "");
+               adder = GUICustomComponentCreator.create(model, pC, "");
+               adder.moveTo(0, 200);
+       }
+
+       @SuppressWarnings("unused") // for GUIWires being created
+       public static void createFromJsonExample(ViewModelModifiable model)
+       {
+               SimpleRectangularSubmodelComponent tmp = new GUIhalfadder(model);
+               tmp.moveTo(1000, 50);
+               RectComponentParams p = tmp.calculateRectParams();
+               try
+               {
+                       p.writeJson("HalfAdder.rc");
+                       p = RectComponentParams.readJson("HalfAdder.rc");
+               }
+               catch (IOException e)
+               {
+                       e.printStackTrace();
+               }
+               tmp = new GUIfulladder(model);
+               SubComponentParams pC = tmp.calculateParams();
+               tmp.moveTo(1000, 100);
+               try
+               {
+                       pC.writeJson("FullAdder.sc");
+                       pC = SubComponentParams.readJson("FullAdder.sc");
+               }
+               catch (IOException e)
+               {
+                       e.printStackTrace();
+               }
+
+               SimpleRectangularSubmodelComponent adder = new GUIfulladder(model);
+
+               GUIManualSwitch swA = new GUIManualSwitch(model);
+               swA.moveTo(0, 0);
+               GUIManualSwitch swB = new GUIManualSwitch(model);
+               swB.moveTo(0, 25);
+               GUIManualSwitch swC = new GUIManualSwitch(model);
+               swC.moveTo(0, 50);
+
+               adder.moveTo(30, 10);
+               GUIBitDisplay bdY = new GUIBitDisplay(model);
+               bdY.moveTo(90, 12.5);
+               GUIBitDisplay bdZ = new GUIBitDisplay(model);
+               bdZ.moveTo(90, 30);
+
+               new GUIWire(model, swA.getOutputPin(), adder.getInputPins().get(0));
+               new GUIWire(model, swB.getOutputPin(), adder.getInputPins().get(1));
+               new GUIWire(model, swC.getOutputPin(), adder.getInputPins().get(2));
+
+               new GUIWire(model, adder.getOutputPins().get(0), bdY.getInputPin());
+               new GUIWire(model, adder.getOutputPins().get(1), bdZ.getInputPin());
+
+               SubmodelComponent adder2 = GUICustomComponentCreator.create(model, pC, "");
+
+               swA = new GUIManualSwitch(model);
+               swA.moveTo(0, 70);
+               swB = new GUIManualSwitch(model);
+               swB.moveTo(0, 85);
+               swC = new GUIManualSwitch(model);
+               swC.moveTo(0, 100);
+
+               adder2.moveTo(30, 80);
+               bdY = new GUIBitDisplay(model);
+               bdY.moveTo(90, 70);
+               bdZ = new GUIBitDisplay(model);
+               bdZ.moveTo(90, 85);
+
+               new GUIWire(model, swA.getOutputPin(), adder2.getPins().get(0));
+               new GUIWire(model, swB.getOutputPin(), adder2.getPins().get(1));
+               new GUIWire(model, swC.getOutputPin(), adder2.getPins().get(2));
+
+               new GUIWire(model, adder2.getPins().get(3), bdY.getInputPin());
+               new GUIWire(model, adder2.getPins().get(4), bdZ.getInputPin());
+       }
+}
\ No newline at end of file
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
deleted file mode 100644 (file)
index 1a273bd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-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();
-       }
-}
index a4c1031..5f74dad 100644 (file)
@@ -129,4 +129,9 @@ public abstract class GUIComponent
                pin.removeRedrawListener(redrawListenerForSubcomponents);
                callRedrawListeners();
        }
+
+       public String getIdentifier()
+       {
+               return "class:".concat(getClass().getCanonicalName());
+       }
 }
\ No newline at end of file
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
deleted file mode 100644 (file)
index 6f84daf..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-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/GUICustomComponentCreator.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponentCreator.java
new file mode 100644 (file)
index 0000000..691f552
--- /dev/null
@@ -0,0 +1,154 @@
+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.params.GeneralComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams;
+import net.mograsim.logic.ui.model.components.params.SubComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerWireParams;
+import net.mograsim.logic.ui.model.components.params.SubComponentParams.InterfacePinParams;
+import net.mograsim.logic.ui.model.wires.GUIWire;
+
+public class GUICustomComponentCreator
+{
+       private static class CustomRectComponent extends SimpleRectangularSubmodelComponent
+       {
+               private String path;
+
+               protected CustomRectComponent(ViewModelModifiable model, int logicWidth, String label, String path)
+               {
+                       super(model, logicWidth, label);
+                       this.path = path;
+               }
+
+               @Override
+               public String getIdentifier()
+               {
+                       return "file:".concat(path);
+               }
+       }
+
+       public static SubmodelComponent create(ViewModelModifiable model, String path)
+       {
+               try
+               {
+                       if (path.endsWith(RectComponentParams.fileExtension))
+                       {
+                               RectComponentParams params = RectComponentParams.readJson(path);
+                               SubmodelComponent ret = create(model, params, path);
+                               return ret;
+                       } else if (path.endsWith(SubComponentParams.fileExtension))
+                       {
+                               SubComponentParams params = SubComponentParams.readJson(path);
+                               SubmodelComponent ret = create(model, params, path);
+                               return ret;
+                       } else
+                               throw new IOException(String.format("\"%s\" does not have a valid file extension. Must be either %s or %s", path,
+                                               RectComponentParams.fileExtension, SubComponentParams.fileExtension));
+               }
+               catch (IOException e)
+               {
+                       System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
+                       e.printStackTrace();
+               }
+               return new CustomRectComponent(model, 0, "ERROR", "NONE");
+       }
+
+       /**
+        * @param path This value is used when the new SubmodelComponent is an inner component to a different SubmodelComponent, which is being
+        *             saved to a file; Then, the new SubmodelComponent is referenced by its given path within the file.
+        */
+       public static SimpleRectangularSubmodelComponent create(ViewModelModifiable model, RectComponentParams params, String path)
+       {
+               CustomRectComponent comp = new CustomRectComponent(model, params.logicWidth, params.displayName, path);
+               comp.setSubmodelScale(params.composition.innerScale);
+               comp.setInputCount(params.inputCount);
+               comp.setOutputCount(params.outputCount);
+               initSubmodelComponents(comp, params.composition);
+               return comp;
+       }
+
+       /**
+        * @param path This value is used when the new SubmodelComponent is an inner component to a different SubmodelComponent, which is being
+        *             saved to a file; Then, the new SubmodelComponent is referenced by its given path within the file.
+        */
+       public static SubmodelComponent create(ViewModelModifiable model, SubComponentParams params, String path)
+       {
+               // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
+               CustomRectComponent comp = new CustomRectComponent(model, 0, "", path);
+               comp.setSubmodelScale(params.composition.innerScale);
+               comp.setSize(params.width, params.height);
+               for (InterfacePinParams iPinParams : params.interfacePins)
+               {
+                       comp.addSubmodelInterface(iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y);
+               }
+               initSubmodelComponents(comp, params.composition);
+               return comp;
+       }
+
+       @SuppressWarnings("unused")
+       private static void initSubmodelComponents(SubmodelComponent comp, GeneralComponentParams 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] = createInnerComponentFromClass(comp, path, cParams.logicWidth);
+                                       components[i].moveTo(cParams.pos.x, cParams.pos.y);
+                               } else if (path.startsWith("file:"))
+                               {
+                                       path = path.substring(5);
+                                       components[i] = create(comp.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(comp.submodelModifiable,
+                                               comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPins().get(innerWire.pin1.pinIndex),
+                                               comp.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 static GUIComponent createInnerComponentFromClass(SubmodelComponent parent, 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(parent.submodelModifiable);
+               }
+               catch (@SuppressWarnings("unused") NoSuchMethodException e)
+               {
+                       Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
+                       comp = constructor.newInstance(parent.submodelModifiable, logicWidth);
+               }
+
+               if (comp instanceof GUIComponent)
+                       return (GUIComponent) comp;
+               throw new IllegalArgumentException("Class given as subcomponent was not a GUIComponent!");
+       }
+}
index f537eec..3373553 100644 (file)
@@ -2,7 +2,6 @@ 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;
@@ -10,10 +9,7 @@ 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.components.params.RectComponentParams;
 import net.mograsim.logic.ui.model.wires.Pin;
 
 public class SimpleRectangularSubmodelComponent extends SubmodelComponent
@@ -128,55 +124,14 @@ public class SimpleRectangularSubmodelComponent extends SubmodelComponent
                gc.drawRectangle(getBounds());
        }
 
-       public ComponentParams calculateParams()
+       public RectComponentParams calculateRectParams()
        {
-               ComponentParams params = new ComponentParams();
+               RectComponentParams params = new RectComponentParams();
                params.displayName = label;
                params.inputCount = inputSupermodelPins.size();
                params.outputCount = outputSubmodelPins.size();
                params.logicWidth = logicWidth;
-               params.innerScale = getSubmodelScale();
-
-               List<GUIComponent> compList = submodelModifiable.getComponents();
-               Iterator<GUIComponent> 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<GUIWire> 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;
+               params.composition = calculateCompositionParams();
                return params;
        }
 }
\ No newline at end of file
index 43ec22b..b9939af 100644 (file)
@@ -2,16 +2,26 @@ package net.mograsim.logic.ui.model.components;
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
 import net.haspamelodica.swt.helper.gcs.GCConfig;
 import net.haspamelodica.swt.helper.gcs.GeneralGC;
 import net.haspamelodica.swt.helper.gcs.TranslatedGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
 import net.mograsim.logic.ui.LogicUIRenderer;
 import net.mograsim.logic.ui.model.ViewModel;
 import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.params.GeneralComponentParams;
+import net.mograsim.logic.ui.model.components.params.SubComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerPinParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerWireParams;
+import net.mograsim.logic.ui.model.components.params.SubComponentParams.InterfacePinParams;
+import net.mograsim.logic.ui.model.wires.GUIWire;
 import net.mograsim.logic.ui.model.wires.Pin;
 
 public abstract class SubmodelComponent extends GUIComponent
@@ -199,4 +209,73 @@ public abstract class SubmodelComponent extends GUIComponent
                        super.setRelPos(relX, relY);
                }
        }
+
+       public SubComponentParams calculateParams()
+       {
+               SubComponentParams params = new SubComponentParams();
+               params.composition = calculateCompositionParams();
+
+               Rectangle bounds = getBounds();
+               params.width = bounds.width;
+               params.height = bounds.height;
+
+               List<Pin> pinList = pinsUnmodifiable;
+               InterfacePinParams[] iPins = new InterfacePinParams[pinList.size()];
+               int i = 0;
+               for (Pin p : pinList)
+               {
+                       InterfacePinParams iPinParams = new InterfacePinParams();
+                       iPins[i] = iPinParams;
+                       iPinParams.location = p.getRelPos();
+                       iPinParams.logicWidth = p.logicWidth;
+                       i++;
+               }
+               params.interfacePins = iPins;
+               return params;
+       }
+
+       protected GeneralComponentParams calculateCompositionParams()
+       {
+               GeneralComponentParams params = new GeneralComponentParams();
+               params.innerScale = getSubmodelScale();
+
+               List<GUIComponent> compList = submodelModifiable.getComponents();
+               Iterator<GUIComponent> 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);
+                       inner.type = component.getIdentifier();
+                       i++;
+               }
+               params.subComps = comps;
+
+               List<GUIWire> 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/params/GeneralComponentParams.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/GeneralComponentParams.java
new file mode 100644 (file)
index 0000000..cf82db4
--- /dev/null
@@ -0,0 +1,11 @@
+package net.mograsim.logic.ui.model.components.params;
+
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerComponentParams;
+import net.mograsim.logic.ui.model.components.params.RectComponentParams.InnerWireParams;
+
+public class GeneralComponentParams
+{
+       public double innerScale;
+       public InnerComponentParams[] subComps;
+       public InnerWireParams[] innerWires;
+}
diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/JsonHandler.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/JsonHandler.java
new file mode 100644 (file)
index 0000000..c80aba7
--- /dev/null
@@ -0,0 +1,30 @@
+package net.mograsim.logic.ui.model.components.params;
+
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class JsonHandler
+{
+       private static Gson parser = new GsonBuilder().setPrettyPrinting().create();
+
+       @SuppressWarnings("resource")
+       public static <T> T readJson(String path, Class<T> type) throws IOException
+       {
+               FileReader reader = new FileReader(path);
+               T params = parser.fromJson(new FileReader(path), type);
+               reader.close();
+               return params;
+       }
+
+       public static void writeJson(Object o, String path) throws IOException
+       {
+               @SuppressWarnings("resource")
+               FileWriter writer = new FileWriter(path);
+               writer.write(parser.toJson(o));
+               writer.close(); // TODO: Insure that writer is closed
+       }
+}
diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/RectComponentParams.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/RectComponentParams.java
new file mode 100644 (file)
index 0000000..8fafaf9
--- /dev/null
@@ -0,0 +1,53 @@
+package net.mograsim.logic.ui.model.components.params;
+
+import java.io.IOException;
+
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+
+public class RectComponentParams
+{
+       public final static String fileExtension = ".rc";
+       public String displayName;
+       public int inputCount, outputCount, logicWidth;
+       public GeneralComponentParams composition;
+
+       public static class InnerComponentParams
+       {
+               public Point pos;
+               public String type;
+               public int logicWidth;
+       }
+
+       public static class InnerWireParams
+       {
+               public InnerPinParams pin1, pin2;
+               public Point[] path;
+       }
+
+       public static class InnerPinParams
+       {
+               public int compId, pinIndex;
+       }
+
+       public static RectComponentParams readJson(String path) throws IOException
+       {
+               return JsonHandler.readJson(path, RectComponentParams.class);
+       }
+
+       /**
+        * Writes this {@link RectComponentParams} object into a file in json format. The correct file extension is important! Check
+        * {@link RectComponentParams}.fileExtension
+        */
+       public void writeJson(String path)
+       {
+               try
+               {
+                       JsonHandler.writeJson(this, path);
+               }
+               catch (IOException e)
+               {
+                       System.err.println("Failed to write RectComponentParams to file");
+                       e.printStackTrace();
+               }
+       }
+}
diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/SubComponentParams.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/SubComponentParams.java
new file mode 100644 (file)
index 0000000..dc05114
--- /dev/null
@@ -0,0 +1,41 @@
+package net.mograsim.logic.ui.model.components.params;
+
+import java.io.IOException;
+
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+
+public class SubComponentParams
+{
+       public final static String fileExtension = ".sc";
+       public double width, height;
+       public InterfacePinParams[] interfacePins;
+       public GeneralComponentParams composition;
+
+       public static class InterfacePinParams
+       {
+               public Point location;
+               public int logicWidth;
+       }
+
+       public static SubComponentParams readJson(String path) throws IOException
+       {
+               return JsonHandler.readJson(path, SubComponentParams.class);
+       }
+
+       /**
+        * Writes this {@link SubComponentParams} object into a file in json format. The correct file extension is important! Check
+        * {@link SubComponentParams}.fileExtension
+        */
+       public void writeJson(String path)
+       {
+               try
+               {
+                       JsonHandler.writeJson(this, path);
+               }
+               catch (IOException e)
+               {
+                       System.err.println("Failed to write SubComponentParams to file");
+                       e.printStackTrace();
+               }
+       }
+}
\ No newline at end of file