From b2f3d0b16783289fab229c667c18d61f84119bbd Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Fri, 14 Jun 2019 15:40:57 +0200 Subject: [PATCH] General SubmodelComponents can now be saved to a json format 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. --- .../logic/ui/examples/JsonExample.java | 146 +++++++++++++++++ .../ui/model/components/ComponentParams.java | 56 ------- .../ui/model/components/GUIComponent.java | 5 + .../model/components/GUICustomComponent.java | 111 ------------- .../components/GUICustomComponentCreator.java | 154 ++++++++++++++++++ .../SimpleRectangularSubmodelComponent.java | 53 +----- .../model/components/SubmodelComponent.java | 79 +++++++++ .../params/GeneralComponentParams.java | 11 ++ .../model/components/params/JsonHandler.java | 30 ++++ .../params/RectComponentParams.java | 53 ++++++ .../components/params/SubComponentParams.java | 41 +++++ 11 files changed, 523 insertions(+), 216 deletions(-) create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/examples/JsonExample.java delete mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java delete mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponentCreator.java create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/GeneralComponentParams.java create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/JsonHandler.java create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/RectComponentParams.java create mode 100644 net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/SubComponentParams.java 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 index 00000000..c6a2e7be --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/examples/JsonExample.java @@ -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 index 1a273bd8..00000000 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/ComponentParams.java +++ /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(); - } -} diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java index a4c1031f..5f74dadd 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java @@ -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 index 6f84daf5..00000000 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponent.java +++ /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 index 00000000..691f552e --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUICustomComponentCreator.java @@ -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!"); + } +} 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 f537eec2..33735530 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,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 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; + params.composition = calculateCompositionParams(); 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 43ec22b0..b9939afe 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 @@ -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 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 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); + inner.type = component.getIdentifier(); + 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/params/GeneralComponentParams.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/GeneralComponentParams.java new file mode 100644 index 00000000..cf82db4b --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/GeneralComponentParams.java @@ -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 index 00000000..c80aba71 --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/JsonHandler.java @@ -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 readJson(String path, Class 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 index 00000000..8fafaf97 --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/RectComponentParams.java @@ -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 index 00000000..dc051140 --- /dev/null +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/params/SubComponentParams.java @@ -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 -- 2.17.1