From: Daniel Kirschten Date: Mon, 15 Jul 2019 14:22:37 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/development' into development X-Git-Url: https://mograsim.net/gitweb/?a=commitdiff_plain;h=6ff37062ffff3ee3499e15b8d8bf532b4eaa6608;hp=13e72d4157b071cbb58942d964f3c0bb00c26029;p=Mograsim.git Merge remote-tracking branch 'origin/development' into development --- diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ComponenetSerializer.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ComponenetSerializer.java index 3d568e36..00478d4d 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ComponenetSerializer.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ComponenetSerializer.java @@ -36,6 +36,7 @@ import net.mograsim.logic.model.model.components.mi.nandbased.am2901.GUIAm2901QR import net.mograsim.logic.model.model.components.mi.nandbased.am2901.GUIAm2901SourceDecode; import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; import net.mograsim.logic.model.serializing.SubmodelComponentParams; +import net.mograsim.logic.model.serializing.SubmodelComponentSerializer; import net.mograsim.logic.model.util.JsonHandler; public class ComponenetSerializer @@ -56,7 +57,7 @@ public class ComponenetSerializer for (SubmodelComponent comp : components) { - SubmodelComponentParams params = comp.calculateParams(getIdentifier); + SubmodelComponentParams params = SubmodelComponentSerializer.serialize(comp, getIdentifier); JsonHandler.writeJson(params, "components/" + comp.getClass().getName().substring("net.mograsim.logic.ui.model.components.mi.nandbased.".length()).replace('.', '/') + ".json"); diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/JsonExample.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/JsonExample.java index 120ceb6c..5f95c3e4 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/JsonExample.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/JsonExample.java @@ -1,6 +1,7 @@ package net.mograsim.logic.model.examples; import java.io.IOException; +import java.io.UncheckedIOException; import com.google.gson.JsonNull; @@ -14,7 +15,7 @@ import net.mograsim.logic.model.model.components.submodels.SimpleRectangularSubm import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; -import net.mograsim.logic.model.serializing.SubmodelComponentDeserializer; +import net.mograsim.logic.model.serializing.SubmodelComponentSerializer; import net.mograsim.logic.model.serializing.SubmodelComponentParams; import net.mograsim.logic.model.util.JsonHandler; @@ -37,7 +38,14 @@ public class JsonExample super(model, 1, "Test", name); setSubmodelScale(.4); setInputPins("Input pin #0"); - SubmodelComponentDeserializer.create(submodelModifiable, "HalfAdder.json", "halfadder"); + try + { + SubmodelComponentSerializer.deserialize(submodelModifiable, "HalfAdder.json", "halfadder"); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } } } @@ -46,11 +54,11 @@ public class JsonExample { GUI_rsLatch comp = new GUI_rsLatch(viewModel, "Original RS latch"); comp.moveTo(30, 0); - SubmodelComponentParams params = comp.calculateParams(); + SubmodelComponentParams params = SubmodelComponentSerializer.serialize(comp); String jsonString = JsonHandler.toJson(params); System.out.println(jsonString); SubmodelComponentParams paramsD = JsonHandler.fromJson(jsonString, SubmodelComponentParams.class); - SubmodelComponent componentD = SubmodelComponentDeserializer.create(viewModel, paramsD, "Deserialized RS latch"); + SubmodelComponent componentD = SubmodelComponentSerializer.deserialize(viewModel, paramsD, "Deserialized RS latch"); componentD.moveTo(30, 50); double h = 0; for (String s : comp.getInputPinNames()) @@ -80,8 +88,16 @@ public class JsonExample public static void refJsonFromJsonTest(ViewModelModifiable model) { TestComponent t = new TestComponent(model, "Original component"); - t.calculateParams().writeJson("Test.json"); - SubmodelComponent c = SubmodelComponentDeserializer.create(model, "Test.json", "Deserialized component"); + SubmodelComponentSerializer.serialize(t).writeJson("Test.json"); + SubmodelComponent c; + try + { + c = SubmodelComponentSerializer.deserialize(model, "Test.json", "Deserialized component"); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } c.moveTo(0, 50); } @@ -89,7 +105,7 @@ public class JsonExample public static void createFromJsonExample(ViewModelModifiable model) { SimpleRectangularSubmodelComponent tmp = new GUIfulladder(model, "Original full adder"); - SubmodelComponentParams pC = tmp.calculateParams(); + SubmodelComponentParams pC = SubmodelComponentSerializer.serialize(tmp); tmp.moveTo(1000, 100); try { @@ -101,8 +117,16 @@ public class JsonExample e.printStackTrace(); } - SimpleRectangularSubmodelComponent adder = (SimpleRectangularSubmodelComponent) SubmodelComponentDeserializer.create(model, - "FullAdder.json", "Deserialized full adder"); + SimpleRectangularSubmodelComponent adder; + try + { + adder = (SimpleRectangularSubmodelComponent) SubmodelComponentSerializer.deserialize(model, "FullAdder.json", + "Deserialized full adder"); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } GUIManualSwitch swA = new GUIManualSwitch(model); swA.moveTo(0, 0); @@ -124,7 +148,7 @@ public class JsonExample new GUIWire(model, adder.getPin("Y"), bdY.getInputPin()); new GUIWire(model, adder.getPin("Z"), bdZ.getInputPin()); - SubmodelComponent adder2 = SubmodelComponentDeserializer.create(model, pC, "Full adder created from params instance"); + SubmodelComponent adder2 = SubmodelComponentSerializer.deserialize(model, pC, "Full adder created from params instance"); swA = new GUIManualSwitch(model); swA.moveTo(0, 70); diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/SubmodelComponentTestbench.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/SubmodelComponentTestbench.java index 0d9c604d..6a42d704 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/SubmodelComponentTestbench.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/SubmodelComponentTestbench.java @@ -1,5 +1,7 @@ package net.mograsim.logic.model.examples; +import java.io.IOException; +import java.io.UncheckedIOException; import java.util.ArrayList; import java.util.List; @@ -10,7 +12,7 @@ import net.mograsim.logic.model.model.components.atomic.GUIManualSwitch; import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.SubmodelComponentDeserializer; +import net.mograsim.logic.model.serializing.SubmodelComponentSerializer; public class SubmodelComponentTestbench { @@ -22,7 +24,15 @@ public class SubmodelComponentTestbench @SuppressWarnings("unused") // for GUIWires being created public static void createTestbench(ViewModelModifiable model) { - SubmodelComponent comp = SubmodelComponentDeserializer.create(model, "components/am2901/GUIAm2901.json"); + SubmodelComponent comp; + try + { + comp = SubmodelComponentSerializer.deserialize(model, "components/am2901/GUIAm2901.json"); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } // guess which pins are outputs and which are inputs // TODO this code exists three times... but it seems too "hacky" to put it in a helper class diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdff.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdff.java index b8a5c8a3..1d67977f 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdff.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdff.java @@ -8,10 +8,12 @@ import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.DelegatingAtomicHighLevelStateHandler; public class GUIdff extends SimpleRectangularSubmodelComponent { - private GUI_rsLatch _rsLatch; + private StandardHighLevelStateHandler highLevelStateHandler; public GUIdff(ViewModelModifiable model) { @@ -38,7 +40,7 @@ public class GUIdff extends SimpleRectangularSubmodelComponent GUI_rsLatch _rsLatch1 = new GUI_rsLatch(submodelModifiable); GUInand3 nand3 = new GUInand3(submodelModifiable); GUINandGate nand2 = new GUINandGate(submodelModifiable, 1); - GUI_rsLatch _rsLatch2 = this._rsLatch = new GUI_rsLatch(submodelModifiable); + GUI_rsLatch _rsLatch2 = new GUI_rsLatch(submodelModifiable); WireCrossPoint cp1 = new WireCrossPoint(submodelModifiable, 1); WireCrossPoint cp2 = new WireCrossPoint(submodelModifiable, 1); @@ -70,34 +72,20 @@ public class GUIdff extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, _rsLatch2.getPin("Q"), Q); new GUIWire(submodelModifiable, _rsLatch2.getPin("_Q"), _Q); - addAtomicHighLevelStateID("q"); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addAtomicHighLevelState("q", DelegatingAtomicHighLevelStateHandler::new).set(_rsLatch2, "q"); } @Override - public void setAtomicHighLevelState(String stateID, Object newState) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q": - _rsLatch.setHighLevelState("q", newState); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - public Object getAtomicHighLevelState(String stateID) + public void setHighLevelState(String stateID, Object newState) { - switch (stateID) - { - case "q": - return _rsLatch.getHighLevelState("q"); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch.java index 7378237d..a6807735 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch.java @@ -8,10 +8,12 @@ import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.DelegatingAtomicHighLevelStateHandler; public class GUIdlatch extends SimpleRectangularSubmodelComponent { - private GUI_rsLatch _rsLatch; + private StandardHighLevelStateHandler highLevelStateHandler; public GUIdlatch(ViewModelModifiable model) { @@ -37,7 +39,7 @@ public class GUIdlatch extends SimpleRectangularSubmodelComponent GUINandGate nand1 = new GUINandGate(submodelModifiable, 1); GUINandGate nand2 = new GUINandGate(submodelModifiable, 1); - _rsLatch = new GUI_rsLatch(submodelModifiable); + GUI_rsLatch _rsLatch = new GUI_rsLatch(submodelModifiable); WireCrossPoint cp1 = new WireCrossPoint(submodelModifiable, 1); WireCrossPoint cp2 = new WireCrossPoint(submodelModifiable, 1); @@ -59,34 +61,20 @@ public class GUIdlatch extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, _rsLatch.getPin("Q"), Q, new Point[0]); new GUIWire(submodelModifiable, _rsLatch.getPin("_Q"), _Q); - addAtomicHighLevelStateID("q"); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addAtomicHighLevelState("q", DelegatingAtomicHighLevelStateHandler::new).set(_rsLatch, "q"); } @Override - public void setAtomicHighLevelState(String stateID, Object newState) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q": - _rsLatch.setHighLevelState("q", newState); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - public Object getAtomicHighLevelState(String stateID) + public void setHighLevelState(String stateID, Object newState) { - switch (stateID) - { - case "q": - return _rsLatch.getHighLevelState("q"); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch4.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch4.java index 875843f6..99dc93c5 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch4.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIdlatch4.java @@ -1,21 +1,21 @@ package net.mograsim.logic.model.model.components.mi.nandbased; +import java.util.Arrays; + import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.mograsim.logic.core.types.Bit; -import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.submodels.SimpleRectangularSubmodelComponent; import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.BitVectorSplittingAtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.DelegatingAtomicHighLevelStateHandler; public class GUIdlatch4 extends SimpleRectangularSubmodelComponent { - private GUIdlatch dlatch1; - private GUIdlatch dlatch2; - private GUIdlatch dlatch3; - private GUIdlatch dlatch4; + private StandardHighLevelStateHandler highLevelStateHandler; public GUIdlatch4(ViewModelModifiable model) { @@ -44,10 +44,10 @@ public class GUIdlatch4 extends SimpleRectangularSubmodelComponent Pin Q3 = getSubmodelPin("Q3"); Pin Q4 = getSubmodelPin("Q4"); - dlatch1 = new GUIdlatch(submodelModifiable); - dlatch2 = new GUIdlatch(submodelModifiable); - dlatch3 = new GUIdlatch(submodelModifiable); - dlatch4 = new GUIdlatch(submodelModifiable); + GUIdlatch dlatch1 = new GUIdlatch(submodelModifiable); + GUIdlatch dlatch2 = new GUIdlatch(submodelModifiable); + GUIdlatch dlatch3 = new GUIdlatch(submodelModifiable); + GUIdlatch dlatch4 = new GUIdlatch(submodelModifiable); WireCrossPoint cp2 = new WireCrossPoint(submodelModifiable, 1); WireCrossPoint cp3 = new WireCrossPoint(submodelModifiable, 1); @@ -77,66 +77,25 @@ public class GUIdlatch4 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, dlatch3.getPin("Q"), Q3, new Point[0]); new GUIWire(submodelModifiable, dlatch4.getPin("Q"), Q4, new Point[0]); - addAtomicHighLevelStateID("q1"); - addAtomicHighLevelStateID("q2"); - addAtomicHighLevelStateID("q3"); - addAtomicHighLevelStateID("q4"); - addAtomicHighLevelStateID("q"); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addAtomicHighLevelState("q1", DelegatingAtomicHighLevelStateHandler::new).set(dlatch1, "q"); + highLevelStateHandler.addAtomicHighLevelState("q2", DelegatingAtomicHighLevelStateHandler::new).set(dlatch2, "q"); + highLevelStateHandler.addAtomicHighLevelState("q3", DelegatingAtomicHighLevelStateHandler::new).set(dlatch3, "q"); + highLevelStateHandler.addAtomicHighLevelState("q4", DelegatingAtomicHighLevelStateHandler::new).set(dlatch4, "q"); + highLevelStateHandler.addAtomicHighLevelState("q", BitVectorSplittingAtomicHighLevelStateHandler::new) + .set(Arrays.asList("q1", "q2", "q3", "q4"), Arrays.asList(1, 1, 1, 1)); } @Override - public void setAtomicHighLevelState(String stateID, Object newState) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q1": - dlatch1.setHighLevelState("q", newState); - break; - case "q2": - dlatch2.setHighLevelState("q", newState); - break; - case "q3": - dlatch3.setHighLevelState("q", newState); - break; - case "q4": - dlatch4.setHighLevelState("q", newState); - break; - case "q": - BitVector newStateCasted = (BitVector) newState; - setHighLevelState("q1", newStateCasted.getLSBit(0)); - setHighLevelState("q2", newStateCasted.getLSBit(1)); - setHighLevelState("q3", newStateCasted.getLSBit(2)); - setHighLevelState("q4", newStateCasted.getLSBit(3)); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - public Object getAtomicHighLevelState(String stateID) + public void setHighLevelState(String stateID, Object newState) { - switch (stateID) - { - case "q1": - return dlatch1.getHighLevelState("q"); - case "q2": - return dlatch2.getHighLevelState("q"); - case "q3": - return dlatch3.getHighLevelState("q"); - case "q4": - return dlatch4.getHighLevelState("q"); - case "q": - Bit q1 = (Bit) getHighLevelState("q1"); - Bit q2 = (Bit) getHighLevelState("q2"); - Bit q3 = (Bit) getHighLevelState("q3"); - Bit q4 = (Bit) getHighLevelState("q4"); - return BitVector.of(q4, q3, q2, q1); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram2.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram2.java index 2ebc1e33..6a01d534 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram2.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram2.java @@ -1,20 +1,21 @@ package net.mograsim.logic.model.model.components.mi.nandbased; +import java.util.Arrays; + import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.submodels.SimpleRectangularSubmodelComponent; import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.BitVectorSplittingAtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.DelegatingSubcomponentHighLevelStateHandler; public class GUIram2 extends SimpleRectangularSubmodelComponent { - private GUIdlatch4 cell00; - private GUIdlatch4 cell01; - private GUIdlatch4 cell10; - private GUIdlatch4 cell11; + private StandardHighLevelStateHandler highLevelStateHandler; public GUIram2(ViewModelModifiable model) { @@ -55,10 +56,10 @@ public class GUIram2 extends SimpleRectangularSubmodelComponent GUIdemux2 demuxA = new GUIdemux2 (submodelModifiable); GUIdemux2 demuxB = new GUIdemux2 (submodelModifiable); GUIand41 weAndB = new GUIand41 (submodelModifiable); - cell00 = new GUIdlatch4 (submodelModifiable); - cell01 = new GUIdlatch4 (submodelModifiable); - cell10 = new GUIdlatch4 (submodelModifiable); - cell11 = new GUIdlatch4 (submodelModifiable); + GUIdlatch4 cell00 = new GUIdlatch4 (submodelModifiable); + GUIdlatch4 cell01 = new GUIdlatch4 (submodelModifiable); + GUIdlatch4 cell10 = new GUIdlatch4 (submodelModifiable); + GUIdlatch4 cell11 = new GUIdlatch4 (submodelModifiable); GUIand41 andA00 = new GUIand41 (submodelModifiable); GUIandor414 andorA01 = new GUIandor414(submodelModifiable); GUIandor414 andorA10 = new GUIandor414(submodelModifiable); @@ -284,46 +285,25 @@ public class GUIram2 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, andorB11.getPin("Y4"), QB4 , new Point(175, 770), new Point(175, 895), new Point(340, 895), new Point(340, 750)); //@formatter:on - addHighLevelStateSubcomponentID("c00", cell00); - addHighLevelStateSubcomponentID("c01", cell01); - addHighLevelStateSubcomponentID("c10", cell10); - addHighLevelStateSubcomponentID("c11", cell11); - addAtomicHighLevelStateID("q"); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addSubcomponentHighLevelState("c00", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, null); + highLevelStateHandler.addSubcomponentHighLevelState("c01", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, null); + highLevelStateHandler.addSubcomponentHighLevelState("c10", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, null); + highLevelStateHandler.addSubcomponentHighLevelState("c11", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, null); + highLevelStateHandler.addAtomicHighLevelState("q", BitVectorSplittingAtomicHighLevelStateHandler::new) + .set(Arrays.asList("c00.q", "c01.q", "c10.q", "c11.q"), Arrays.asList(4, 4, 4, 4)); } @Override - public void setAtomicHighLevelState(String stateID, Object newState) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q": - BitVector newStateCasted = (BitVector) newState; - setHighLevelState("c00.q", newStateCasted.subVector(0, 4)); - setHighLevelState("c01.q", newStateCasted.subVector(4, 8)); - setHighLevelState("c10.q", newStateCasted.subVector(8, 12)); - setHighLevelState("c11.q", newStateCasted.subVector(12, 16)); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - public Object getAtomicHighLevelState(String stateID) + public void setHighLevelState(String stateID, Object newState) { - switch (stateID) - { - case "q": - BitVector q00 = (BitVector) getHighLevelState("c00.q"); - BitVector q01 = (BitVector) getHighLevelState("c01.q"); - BitVector q10 = (BitVector) getHighLevelState("c10.q"); - BitVector q11 = (BitVector) getHighLevelState("c11.q"); - return q00.concat(q01).concat(q10).concat(q11); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram4.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram4.java index 903a227f..de4e2e7b 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram4.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/GUIram4.java @@ -1,16 +1,22 @@ package net.mograsim.logic.model.model.components.mi.nandbased; +import java.util.Arrays; + import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.submodels.SimpleRectangularSubmodelComponent; import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.BitVectorSplittingAtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.DelegatingSubcomponentHighLevelStateHandler; public class GUIram4 extends SimpleRectangularSubmodelComponent { + private StandardHighLevelStateHandler highLevelStateHandler; + public GUIram4(ViewModelModifiable model) { this(model, null); @@ -287,81 +293,43 @@ public class GUIram4 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, andorA11.getPin("Y4"), QA4 , new Point(195, 770), new Point(195, 895), new Point(325, 895), new Point(325, 350)); //@formatter:on - addHighLevelStateSubcomponentID("c00", cell00); - addHighLevelStateSubcomponentID("c01", cell01); - addHighLevelStateSubcomponentID("c10", cell10); - addHighLevelStateSubcomponentID("c11", cell11); - addAtomicHighLevelStateID("q"); - } + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addSubcomponentHighLevelState("c00", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, null); + highLevelStateHandler.addSubcomponentHighLevelState("c01", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, null); + highLevelStateHandler.addSubcomponentHighLevelState("c10", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, null); + highLevelStateHandler.addSubcomponentHighLevelState("c11", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, null); - @Override - public void setAtomicHighLevelState(String stateID, Object newState) - { - switch (stateID) - { - case "q": - BitVector newStateCasted = (BitVector) newState; - setHighLevelState("c00.q", newStateCasted.subVector(0, 16)); - setHighLevelState("c01.q", newStateCasted.subVector(16, 32)); - setHighLevelState("c10.q", newStateCasted.subVector(32, 48)); - setHighLevelState("c11.q", newStateCasted.subVector(48, 64)); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } - } - - @Override - protected void setSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID, Object newState) - { - if (checkSubcomponentID(subcomponentID)) - setHighLevelState(translateDirectCellAccess(subcomponentID, subcomponentHighLevelStateID), newState); - else - super.setSubcomponentHighLevelState(subcomponentID, subcomponentHighLevelStateID, newState); + highLevelStateHandler.addSubcomponentHighLevelState("c0000", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, "c00"); + highLevelStateHandler.addSubcomponentHighLevelState("c0001", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, "c00"); + highLevelStateHandler.addSubcomponentHighLevelState("c0010", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, "c00"); + highLevelStateHandler.addSubcomponentHighLevelState("c0011", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, "c00"); + highLevelStateHandler.addSubcomponentHighLevelState("c0100", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, "c01"); + highLevelStateHandler.addSubcomponentHighLevelState("c0101", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, "c01"); + highLevelStateHandler.addSubcomponentHighLevelState("c0110", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, "c01"); + highLevelStateHandler.addSubcomponentHighLevelState("c0111", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, "c01"); + highLevelStateHandler.addSubcomponentHighLevelState("c1000", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, "c10"); + highLevelStateHandler.addSubcomponentHighLevelState("c1001", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, "c10"); + highLevelStateHandler.addSubcomponentHighLevelState("c1010", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, "c10"); + highLevelStateHandler.addSubcomponentHighLevelState("c1011", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, "c10"); + highLevelStateHandler.addSubcomponentHighLevelState("c1100", DelegatingSubcomponentHighLevelStateHandler::new).set(cell00, "c11"); + highLevelStateHandler.addSubcomponentHighLevelState("c1101", DelegatingSubcomponentHighLevelStateHandler::new).set(cell01, "c11"); + highLevelStateHandler.addSubcomponentHighLevelState("c1110", DelegatingSubcomponentHighLevelStateHandler::new).set(cell10, "c11"); + highLevelStateHandler.addSubcomponentHighLevelState("c1111", DelegatingSubcomponentHighLevelStateHandler::new).set(cell11, "c11"); + highLevelStateHandler.addAtomicHighLevelState("q", BitVectorSplittingAtomicHighLevelStateHandler::new) + .set(Arrays.asList("c00.q", "c01.q", "c10.q", "c11.q"), Arrays.asList(16, 16, 16, 16)); } @Override - public Object getAtomicHighLevelState(String stateID) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q": - BitVector q00 = (BitVector) getHighLevelState("c00.q"); - BitVector q01 = (BitVector) getHighLevelState("c01.q"); - BitVector q10 = (BitVector) getHighLevelState("c10.q"); - BitVector q11 = (BitVector) getHighLevelState("c11.q"); - return q00.concat(q01).concat(q10).concat(q11); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - protected Object getSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID) - { - if (checkSubcomponentID(subcomponentID)) - return getHighLevelState(translateDirectCellAccess(subcomponentID, subcomponentHighLevelStateID)); - return super.getSubcomponentHighLevelState(subcomponentID, subcomponentHighLevelStateID); - } - - private static String translateDirectCellAccess(String subcomponentID, String subcomponentHighLevelStateID) - { - return 'c' + subcomponentID.substring(3, 5) + "." + subcomponentID.substring(0, 3) + '.' + subcomponentHighLevelStateID; - } - - private static boolean checkSubcomponentID(String subcomponentID) + public void setHighLevelState(String stateID, Object newState) { - if (subcomponentID.length() != 5 || subcomponentID.charAt(0) != 'c') - return false; - char addr3 = subcomponentID.charAt(1); - char addr2 = subcomponentID.charAt(2); - char addr1 = subcomponentID.charAt(3); - char addr0 = subcomponentID.charAt(4); - return (addr3 == '0' || addr3 == '1') || (addr2 == '0' || addr2 == '1') || (addr1 == '0' || addr1 == '1') - || (addr0 == '0' || addr0 == '1'); + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901.java index aca03d9b..466ce97e 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901.java @@ -14,9 +14,13 @@ import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.DelegatingSubcomponentHighLevelStateHandler; public class GUIAm2901 extends SimpleRectangularSubmodelComponent { + private StandardHighLevelStateHandler highLevelStateHandler; + public GUIAm2901(ViewModelModifiable model) { this(model, null); @@ -346,8 +350,21 @@ public class GUIAm2901 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, cpFneq0, notFneq0.getPin("B"), new Point(315, 455)); new GUIWire(submodelModifiable, notFneq0.getPin("Y"), Feq0, new Point[0]); - addHighLevelStateSubcomponentID("regs", ram); - addHighLevelStateSubcomponentID("qreg", qreg); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addSubcomponentHighLevelState("regs", DelegatingSubcomponentHighLevelStateHandler::new).set(ram, null); + highLevelStateHandler.addSubcomponentHighLevelState("qreg", DelegatingSubcomponentHighLevelStateHandler::new).set(qreg, null); + } + + @Override + public Object getHighLevelState(String stateID) + { + return highLevelStateHandler.getHighLevelState(stateID); + } + + @Override + public void setHighLevelState(String stateID, Object newState) + { + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901QReg.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901QReg.java index efae9afc..874d69df 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901QReg.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/model/components/mi/nandbased/am2901/GUIAm2901QReg.java @@ -1,8 +1,8 @@ package net.mograsim.logic.model.model.components.mi.nandbased.am2901; +import java.util.Arrays; + import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.mograsim.logic.core.types.Bit; -import net.mograsim.logic.core.types.BitVector; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.mi.nandbased.GUIand; import net.mograsim.logic.model.model.components.mi.nandbased.GUIdff; @@ -11,13 +11,13 @@ import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.Pin; import net.mograsim.logic.model.model.wires.WireCrossPoint; import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.BitVectorSplittingAtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.DelegatingAtomicHighLevelStateHandler; public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent { - private GUIdff dff1; - private GUIdff dff2; - private GUIdff dff3; - private GUIdff dff4; + private StandardHighLevelStateHandler highLevelStateHandler; public GUIAm2901QReg(ViewModelModifiable model) { @@ -48,10 +48,10 @@ public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent Pin Q4 = getSubmodelPin("Q4"); GUIand and = new GUIand(submodelModifiable); - dff1 = new GUIdff(submodelModifiable); - dff2 = new GUIdff(submodelModifiable); - dff3 = new GUIdff(submodelModifiable); - dff4 = new GUIdff(submodelModifiable); + GUIdff dff1 = new GUIdff(submodelModifiable); + GUIdff dff2 = new GUIdff(submodelModifiable); + GUIdff dff3 = new GUIdff(submodelModifiable); + GUIdff dff4 = new GUIdff(submodelModifiable); WireCrossPoint cpC1 = new WireCrossPoint(submodelModifiable, 1); WireCrossPoint cpC2 = new WireCrossPoint(submodelModifiable, 1); @@ -85,66 +85,25 @@ public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, dff3.getPin("Q"), Q3, new Point[0]); new GUIWire(submodelModifiable, dff4.getPin("Q"), Q4, new Point[0]); - addAtomicHighLevelStateID("q1"); - addAtomicHighLevelStateID("q2"); - addAtomicHighLevelStateID("q3"); - addAtomicHighLevelStateID("q4"); - addAtomicHighLevelStateID("q"); + this.highLevelStateHandler = new StandardHighLevelStateHandler(this); + highLevelStateHandler.addAtomicHighLevelState("q1", DelegatingAtomicHighLevelStateHandler::new).set(dff1, "q"); + highLevelStateHandler.addAtomicHighLevelState("q2", DelegatingAtomicHighLevelStateHandler::new).set(dff2, "q"); + highLevelStateHandler.addAtomicHighLevelState("q3", DelegatingAtomicHighLevelStateHandler::new).set(dff3, "q"); + highLevelStateHandler.addAtomicHighLevelState("q4", DelegatingAtomicHighLevelStateHandler::new).set(dff4, "q"); + highLevelStateHandler.addAtomicHighLevelState("q", BitVectorSplittingAtomicHighLevelStateHandler::new) + .set(Arrays.asList("q1", "q2", "q3", "q4"), Arrays.asList(1, 1, 1, 1)); } @Override - public void setAtomicHighLevelState(String stateID, Object newState) + public Object getHighLevelState(String stateID) { - switch (stateID) - { - case "q1": - dff1.setHighLevelState("q", newState); - break; - case "q2": - dff2.setHighLevelState("q", newState); - break; - case "q3": - dff3.setHighLevelState("q", newState); - break; - case "q4": - dff4.setHighLevelState("q", newState); - break; - case "q": - BitVector newStateCasted = (BitVector) newState; - setHighLevelState("q1", newStateCasted.getLSBit(0)); - setHighLevelState("q2", newStateCasted.getLSBit(1)); - setHighLevelState("q3", newStateCasted.getLSBit(2)); - setHighLevelState("q4", newStateCasted.getLSBit(3)); - break; - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + return highLevelStateHandler.getHighLevelState(stateID); } @Override - public Object getAtomicHighLevelState(String stateID) + public void setHighLevelState(String stateID, Object newState) { - switch (stateID) - { - case "q1": - return dff1.getHighLevelState("q"); - case "q2": - return dff2.getHighLevelState("q"); - case "q3": - return dff3.getHighLevelState("q"); - case "q4": - return dff4.getHighLevelState("q"); - case "q": - Bit q1 = (Bit) getHighLevelState("q1"); - Bit q2 = (Bit) getHighLevelState("q2"); - Bit q3 = (Bit) getHighLevelState("q3"); - Bit q4 = (Bit) getHighLevelState("q4"); - return BitVector.of(q4, q3, q2, q1); - default: - // should not happen because we tell SubmodelComponent to only allow these state IDs. - throw new IllegalStateException("Illegal atomic state ID: " + stateID); - } + highLevelStateHandler.setHighLevelState(stateID, newState); } static diff --git a/net.mograsim.logic.model/META-INF/MANIFEST.MF b/net.mograsim.logic.model/META-INF/MANIFEST.MF index 61a85d19..6da2e2a9 100644 --- a/net.mograsim.logic.model/META-INF/MANIFEST.MF +++ b/net.mograsim.logic.model/META-INF/MANIFEST.MF @@ -13,10 +13,13 @@ Export-Package: net.mograsim.logic.model, net.mograsim.logic.model.modeladapter, net.mograsim.logic.model.modeladapter.componentadapters, net.mograsim.logic.model.serializing, - net.mograsim.logic.model.serializing.snippets, - net.mograsim.logic.model.serializing.snippets.highlevelstatehandlers, - net.mograsim.logic.model.serializing.snippets.outlinerenderers, - net.mograsim.logic.model.serializing.snippets.symbolrenderers, + net.mograsim.logic.model.snippets, + net.mograsim.logic.model.snippets.highlevelstatehandlers, + net.mograsim.logic.model.snippets.highlevelstatehandlers.standard, + net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic, + net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent, + net.mograsim.logic.model.snippets.outlinerenderers, + net.mograsim.logic.model.snippets.symbolrenderers, net.mograsim.logic.model.util Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.swt;bundle-version="3.0.0";visibility:=reexport, diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java index 1b97cd31..4baf3352 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java @@ -14,11 +14,13 @@ import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.snippets.HighLevelStateHandler; +import net.mograsim.logic.model.snippets.HighLevelStateHandler; /** * The base class for all GUI components.
- * A GUIComponent has a position and size. The size can only be modified by subclasses.
+ * A GUIComponent has a reference to the ViewModel it belongs to.
+ * A GUIComponent has a name. This name is unique in the model the GUIComponent belongs to.
+ * A GUIComponent has a position and size. The size can only be modified by subclasses. * * @author Daniel Kirschten */ @@ -148,7 +150,7 @@ public abstract class GUIComponent /** * Sets the given high-level state to the given value.
- * See {@link HighLevelStateHandler#setHighLevelState(String, Object)} for an explanation of high-level state IDs. + * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. * * @see #getHighLevelState(String) * @see HighLevelStateHandler#setHighLevelState(String, Object) @@ -163,7 +165,7 @@ public abstract class GUIComponent /** * Gets the current value of the given high-level state.
- * See {@link HighLevelStateHandler#setHighLevelState(String, Object)} for an explanation of high-level state IDs. + * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. * * @see #setHighLevelState(String, Object) * @see HighLevelStateHandler#getHighLevelState(String) @@ -277,7 +279,7 @@ public abstract class GUIComponent // serializing @SuppressWarnings("static-method") // this method is intended to be overridden - public JsonElement getParams() + public JsonElement getParamsForSerializing() { return JsonNull.INSTANCE; } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/SimpleRectangularGUIGate.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/SimpleRectangularGUIGate.java index c7c26072..9535d3b8 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/SimpleRectangularGUIGate.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/SimpleRectangularGUIGate.java @@ -91,10 +91,10 @@ public class SimpleRectangularGUIGate extends GUIComponent * {@link SimpleRectangularGUIGate}s implementation returns a {@link JsonPrimitive} of type int containing the {@link #logicWidth} of * this component. * - * @see GUIComponent#getParams() + * @see GUIComponent#getParamsForSerializing() */ @Override - public JsonElement getParams() + public JsonElement getParamsForSerializing() { return new JsonPrimitive(logicWidth); } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/TextComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/TextComponent.java index 64a6165e..87c3cf47 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/TextComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/atomic/TextComponent.java @@ -49,7 +49,7 @@ public class TextComponent extends GUIComponent // serializing @Override - public JsonElement getParams() + public JsonElement getParamsForSerializing() { return new JsonPrimitive(text); } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SimpleRectangularSubmodelComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SimpleRectangularSubmodelComponent.java index 530f0789..039cdab6 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SimpleRectangularSubmodelComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SimpleRectangularSubmodelComponent.java @@ -5,33 +5,28 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.function.Function; import org.eclipse.swt.graphics.Color; -import com.google.gson.JsonObject; - import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.model.model.ViewModelModifiable; -import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.model.wires.MovablePin; import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.SubmodelComponentParams; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer; -import net.mograsim.logic.model.serializing.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams; +import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer; +import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams; import net.mograsim.preferences.Preferences; public class SimpleRectangularSubmodelComponent extends SubmodelComponent { - private static final double width = 35; - private static final double pinDistance = 10; - private static final double pinNameMargin = .5; - private static final double labelFontHeight = 5; - private static final double pinNameFontHeight = 3.5; + public static final double width = 35; + public static final double pinDistance = 10; + public static final double pinNameMargin = .5; + public static final double labelFontHeight = 5; + public static final double pinNameFontHeight = 3.5; - private final String label; + public final String label; protected final int logicWidth; private final List inputPinNames; @@ -126,23 +121,6 @@ public class SimpleRectangularSubmodelComponent extends SubmodelComponent gc.drawRectangle(getBounds()); } - // serializing - - @Override - public SubmodelComponentParams calculateParams(Function getIdentifier) - { - SubmodelComponentParams params = super.calculateParams(getIdentifier); - JsonObject symbolRendererParams = new JsonObject(); - symbolRendererParams.addProperty("centerText", label); - symbolRendererParams.addProperty("horizontalComponentCenter", getWidth() / 2); - symbolRendererParams.addProperty("centerTextHeight", labelFontHeight); - symbolRendererParams.addProperty("pinLabelHeight", pinNameFontHeight); - symbolRendererParams.addProperty("pinLabelMargin", pinNameMargin); - params.symbolRendererSnippetID = "SimpleRectangularLikeSymbolRenderer"; - params.symbolRendererParams = symbolRendererParams; - return params; - } - @Override protected Pin addSubmodelInterface(MovablePin supermodelPin) { diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java index b19f05de..b5c1762b 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/submodels/SubmodelComponent.java @@ -2,39 +2,28 @@ package net.mograsim.logic.model.model.components.submodels; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; -import java.util.function.Function; 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.model.LogicUIRenderer; import net.mograsim.logic.model.model.ViewModel; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.wires.GUIWire; import net.mograsim.logic.model.model.wires.MovablePin; import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.SubmodelComponentParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.InterfacePinParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerComponentParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams.InnerPinParams; /** * A {@link GUIComponent} consisting of another model. A SubmodelComponent can have so-called "interface pins" connecting the * inner and outer models. */ +//TODO override getParams public abstract class SubmodelComponent extends GUIComponent { - private static final String SUBMODEL_INTERFACE_NAME = "_submodelinterface"; + public static final String SUBMODEL_INTERFACE_NAME = "_submodelinterface"; /** * A modifiable view of {@link #submodel}. */ @@ -72,15 +61,6 @@ public abstract class SubmodelComponent extends GUIComponent */ private final SubmodelInterface submodelInterface; - /** - * The list of all high level state IDs this component supports without delegating to subcomponents. - */ - private final Set highLevelAtomicStates; - /** - * A map of high level state subcomponent IDs to the {@link GUIComponent} high level state access requests are delegated to. - */ - private final Map subcomponentsByHighLevelStateSubcomponentID; - /** * The factor by which the submodel is scaled when rendering. */ @@ -115,9 +95,6 @@ public abstract class SubmodelComponent extends GUIComponent this.supermodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins); this.submodelInterface = new SubmodelInterface(submodelModifiable, SUBMODEL_INTERFACE_NAME); - this.highLevelAtomicStates = new HashSet<>(); - this.subcomponentsByHighLevelStateSubcomponentID = new HashMap<>(); - this.submodelScale = 1; this.maxVisibleRegionFillRatioForAlpha0 = 0.4; this.minVisibleRegionFillRatioForAlpha1 = 0.8; @@ -264,153 +241,6 @@ public abstract class SubmodelComponent extends GUIComponent return supermodelPins.get(name); } - // high-level access - - /** - * Adds the given subcomponent ID to the set of allowed subcomponent IDs and links the given {@link GUIComponent} as the delegate target - * for this subcomponent ID.
- * Note that this method does not affect whether {@link #setSubcomponentHighLevelState(String, String, Object) - * set}/{@link #getSubcomponentHighLevelState(String, String)} will be called.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about subcomponent IDs. - * - * @author Daniel Kirschten - */ - protected void addHighLevelStateSubcomponentID(String subcomponentID, GUIComponent subcomponent) - { - checkHighLevelStateIDPart(subcomponentID); - subcomponentsByHighLevelStateSubcomponentID.put(subcomponentID, subcomponent); - } - - /** - * Removes the given subcomponent ID from the set of allowed subcomponent IDs.
- * Note that this method does not affect whether {@link #setSubcomponentHighLevelState(String, String, Object) - * set}/{@link #getSubcomponentHighLevelState(String, String)} will be called.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about subcomponent IDs. - * - * @author Daniel Kirschten - */ - protected void removeHighLevelStateSubcomponentID(String subcomponentID) - { - subcomponentsByHighLevelStateSubcomponentID.remove(subcomponentID); - } - - /** - * Adds the given atomic state ID to the set of allowed atomic state IDs.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about atomic state IDs. - * - * @author Daniel Kirschten - */ - protected void addAtomicHighLevelStateID(String stateID) - { - checkHighLevelStateIDPart(stateID); - highLevelAtomicStates.add(stateID); - } - - /** - * Removes the given atomic state ID from the set of allowed atomic state IDs.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about atomic state IDs. - * - * @author Daniel Kirschten - */ - protected void removeAtomicHighLevelStateID(String stateID) - { - highLevelAtomicStates.remove(stateID); - } - - @Override - public final void setHighLevelState(String stateID, Object newState) - { - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot == -1) - if (highLevelAtomicStates.contains(stateID)) - setAtomicHighLevelState(stateID, newState); - else - super.setHighLevelState(stateID, newState); - else - setSubcomponentHighLevelState(stateID.substring(0, indexOfDot), stateID.substring(indexOfDot + 1), newState); - } - - /** - * This method is called in {@link #setHighLevelState(String, Object)} when the state ID is not atomic. The default implementation uses - * the information given to {@link #addHighLevelStateSubcomponentID(String, GUIComponent) - * add}/{@link #removeHighLevelStateSubcomponentID(String)} to decide which subcomponent to delegate to.
- * Note that {@link #addHighLevelStateSubcomponentID(String, GUIComponent) add}/{@link #removeHighLevelStateSubcomponentID(String)} - * don't affect whether this method will be called. - * - * @author Daniel Kirschten - */ - protected void setSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID, Object newState) - { - GUIComponent subcomponent = subcomponentsByHighLevelStateSubcomponentID.get(subcomponentID); - if (subcomponent != null) - subcomponent.setHighLevelState(subcomponentHighLevelStateID, newState); - else - super.setHighLevelState(subcomponentID + "." + subcomponentHighLevelStateID, newState); - } - - /** - * This method is called in {@link #setHighLevelState(String, Object)} when the state ID is atomic and in the set of allowed atomic - * state IDs.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about atomic state IDs. - * - * @author Daniel Kirschten - */ - @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden - protected void setAtomicHighLevelState(String stateID, Object newState) - { - throw new IllegalStateException("Unknown high level state ID: " + stateID); - } - - @Override - public final Object getHighLevelState(String stateID) - { - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot == -1) - { - if (highLevelAtomicStates.contains(stateID)) - return getAtomicHighLevelState(stateID); - return super.getHighLevelState(stateID); - } - return getSubcomponentHighLevelState(stateID.substring(0, indexOfDot), stateID.substring(indexOfDot + 1)); - } - - /** - * This method is called in {@link #getHighLevelState(String, Object)} when the state ID is not atomic. The default implementation uses - * the information given to {@link #addHighLevelStateSubcomponentID(String, GUIComponent) - * add}/{@link #removeHighLevelStateSubcomponentID(String)} to decide which subcomponent to delegate to.
- * Note that {@link #addHighLevelStateSubcomponentID(String, GUIComponent) add}/{@link #removeHighLevelStateSubcomponentID(String)} - * don't affect whether this method will be called. - * - * @author Daniel Kirschten - */ - protected Object getSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID) - { - GUIComponent subcomponent = subcomponentsByHighLevelStateSubcomponentID.get(subcomponentID); - if (subcomponent != null) - return subcomponent.getHighLevelState(subcomponentHighLevelStateID); - return super.getHighLevelState(subcomponentID + "." + subcomponentHighLevelStateID); - } - - /** - * This method is called in {@link SubmodelComponent#getHighLevelState(String)} when the state ID is in the set of allowed atomic state - * IDs.
- * See {@link GUIComponent#setHighLevelState(String, Object)} for details about atomic state IDs. - * - * @author Daniel Kirschten - */ - @SuppressWarnings("static-method") // this method is intended to be overridden - protected Object getAtomicHighLevelState(String stateID) - { - throw new IllegalStateException("Unknown high level state ID: " + stateID); - } - - private static void checkHighLevelStateIDPart(String stateIDPart) - { - if (stateIDPart.indexOf('.') != -1) - throw new IllegalArgumentException("Illegal high level state ID part (contains dot): " + stateIDPart); - - } - // "graphical" operations /** @@ -434,7 +264,7 @@ public abstract class SubmodelComponent extends GUIComponent * * @author Daniel Kirschten */ - protected double getSubmodelScale() + public double getSubmodelScale() { return submodelScale; } @@ -498,84 +328,6 @@ public abstract class SubmodelComponent extends GUIComponent return false; } - // serializing - - // TODO move the methods below to serializing classes - - public SubmodelComponentParams calculateParams() - { - return calculateParams(c -> "class:" + c.getClass().getCanonicalName()); - } - - /** - * @return {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}. - */ - public SubmodelComponentParams calculateParams(Function getIdentifier) - { - SubmodelComponentParams params = new SubmodelComponentParams(); - params.submodel = calculateSubmodelParams(getIdentifier); - - params.width = getWidth(); - params.height = getHeight(); - - InterfacePinParams[] iPins = new InterfacePinParams[getPins().size()]; - int i = 0; - for (Pin p : getPins().values()) - { - InterfacePinParams iPinParams = new InterfacePinParams(); - iPins[i] = iPinParams; - iPinParams.location = p.getRelPos(); - iPinParams.name = p.name; - iPinParams.logicWidth = p.logicWidth; - i++; - } - params.interfacePins = iPins; - return params; - } - - private SubmodelParameters calculateSubmodelParams(Function getIdentifier) - { - SubmodelParameters params = new SubmodelParameters(); - params.innerScale = getSubmodelScale(); - - Map components = new HashMap<>(submodel.getComponentsByName()); - components.remove(SUBMODEL_INTERFACE_NAME); - InnerComponentParams[] comps = new InnerComponentParams[components.size()]; - int i = 0; - for (GUIComponent component : components.values()) - { - InnerComponentParams inner = new InnerComponentParams(); - comps[i] = inner; - inner.pos = new Point(component.getPosX(), component.getPosY()); - inner.id = getIdentifier.apply(component); - inner.params = component.getParams(); - inner.name = component.name; - i++; - } - params.subComps = comps; - - List wireList = submodel.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.pinName = wire.getPin1().name; - pin1Params.compName = wire.getPin1().component.name; - pin2Params.pinName = wire.getPin2().name; - pin2Params.compName = wire.getPin2().component.name; - inner.pin1 = pin1Params; - inner.pin2 = pin2Params; - inner.path = wire.getPath(); - i++; - } - params.innerWires = wires; - return params; - } - // operations no longer supported @Override diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/WireCrossPoint.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/WireCrossPoint.java index 52db2777..f7150a2a 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/WireCrossPoint.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/WireCrossPoint.java @@ -115,7 +115,7 @@ public class WireCrossPoint extends GUIComponent // serializing @Override - public JsonElement getParams() + public JsonElement getParamsForSerializing() { return new JsonPrimitive(pin.logicWidth); } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/CodeSnippetSupplier.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/CodeSnippetSupplier.java deleted file mode 100644 index f9f151b5..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/CodeSnippetSupplier.java +++ /dev/null @@ -1,117 +0,0 @@ -package net.mograsim.logic.model.serializing; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import net.mograsim.logic.model.serializing.snippets.HighLevelStateHandler; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.highlevelstatehandlers.DefaultHighLevelStateHandler; -import net.mograsim.logic.model.serializing.snippets.outlinerenderers.DefaultOutlineRenderer; -import net.mograsim.logic.model.serializing.snippets.symbolrenderers.DefaultSymbolRenderer; -import net.mograsim.logic.model.util.JsonHandler; - -public class CodeSnippetSupplier -{ - // public static members - public static final CodeSnippetSupplier symbolRendererSupplier; - public static final CodeSnippetSupplier outlineRendererSupplier; - public static final CodeSnippetSupplier highLevelStateHandlerSupplier; - - static - { - symbolRendererSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultSymbolRenderer::new)); - outlineRendererSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultOutlineRenderer::new)); - highLevelStateHandlerSupplier = new CodeSnippetSupplier<>(SnippetSupplier.create(Void.class, DefaultHighLevelStateHandler::new)); - } - - // per-instance members - - private final Map standardSnippetIDClassNames = new HashMap<>(); - private final Map> snippetSuppliersForClassNames = new HashMap<>(); - private final SnippetSupplier defaultSnippetSupplier; - - private CodeSnippetSupplier(SnippetSupplier defaultSnippetSupplier) - { - this.defaultSnippetSupplier = defaultSnippetSupplier; - } - - public void addStandardSnippetID(String standardSnippetID, String associatedSnippetClassName) - { - standardSnippetIDClassNames.put(standardSnippetID, associatedSnippetClassName); - } - - public void setSnippetSupplier(String id, SnippetSupplier snippetSupplier) - { - snippetSuppliersForClassNames.put(id, snippetSupplier); - } - - // TODO report errors - public SnippetSupplier getSnippetSupplier(String id) - { - if (id != null) - { - String snippetClassName; - if (id.startsWith("class:")) - snippetClassName = id.substring(6); - else - snippetClassName = standardSnippetIDClassNames.get(id); - if (snippetClassName != null) - { - tryLoadSnippetClass(snippetClassName); - SnippetSupplier snippetSupplier = snippetSuppliersForClassNames.get(snippetClassName); - if (snippetSupplier != null) - return snippetSupplier; - } - System.err.println("Couldn't load snippet " + id + "; using default"); - } - return defaultSnippetSupplier; - } - - // static helpers - - static - { - try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./standardSnippetIDMapping.json")) - { - if (s == null) - throw new IOException("Resource not found"); - SnippetIDClassNames tmp = JsonHandler.readJson(s, SnippetIDClassNames.class); - tmp.standardOutlineRendererSuppliers.forEach(outlineRendererSupplier::addStandardSnippetID); - tmp.standardSymbolRendererSuppliers.forEach(symbolRendererSupplier::addStandardSnippetID); - tmp.standardHighLevelStateHandlerSuppliers.forEach(highLevelStateHandlerSupplier::addStandardSnippetID); - } - catch (Exception e) - { - System.err.println("Failed to initialize standard snippet ID mapping: "); - e.printStackTrace(); - } - } - - private static class SnippetIDClassNames - { - public Map standardOutlineRendererSuppliers; - public Map standardSymbolRendererSuppliers; - public Map standardHighLevelStateHandlerSuppliers; - } - - private static void tryLoadSnippetClass(String snippetClassName) - { - tryInvokeStaticInitializer(snippetClassName, "Error getting snippet class: %s: %s\n"); - } - - public static void tryInvokeStaticInitializer(String className, String errorMessageFormat) - { - try - { - Class.forName(className, true, CodeSnippetSupplier.class.getClassLoader()); - } - catch (ClassNotFoundException e) - { - System.err.printf(errorMessageFormat, className, "ClassNotFoundException thrown: " + e.getMessage()); - } - } - -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/DeserializedSubmodelComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/DeserializedSubmodelComponent.java index adf24338..8109a37f 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/DeserializedSubmodelComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/DeserializedSubmodelComponent.java @@ -2,22 +2,56 @@ package net.mograsim.logic.model.serializing; import java.util.Map; +import com.google.gson.JsonElement; + import net.haspamelodica.swt.helper.gcs.GeneralGC; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; import net.mograsim.logic.model.model.wires.MovablePin; import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.snippets.Renderer; +import net.mograsim.logic.model.snippets.HighLevelStateHandler; +import net.mograsim.logic.model.snippets.Renderer; +//TODO serialize handlers public class DeserializedSubmodelComponent extends SubmodelComponent { - public Renderer outlineRenderer; - public Renderer symbolRenderer; + /** + * If a DeserializedSubmodelComponent is part of another SubmodelComponent, when it it serialized, it should not return its internal + * structure, but rather the component ID used to create it. + * + * @see SubmodelComponentSerializer#deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement) + * SubmodelComponentSerializer.deserialize(...) + * @see SubmodelComponentSerializer#serialize(SubmodelComponent, java.util.function.Function) SubmodelComponentSerializer.serialize(...) + */ + public final String idForSerializingOverride; + /** + * See {@link #idForSerializingOverride} + */ + public final JsonElement paramsForSerializingOverride; + + private Renderer outlineRenderer; + private Renderer symbolRenderer; + private HighLevelStateHandler highLevelStateHandler; - public DeserializedSubmodelComponent(ViewModelModifiable model, String name) + public DeserializedSubmodelComponent(ViewModelModifiable model, String name, String idForSerializingOverride, + JsonElement paramsForSerializingOverride) { super(model, name); + this.idForSerializingOverride = idForSerializingOverride; + this.paramsForSerializingOverride = paramsForSerializingOverride; + } + + @Override + public void setHighLevelState(String stateID, Object newState) + { + highLevelStateHandler.setHighLevelState(stateID, newState); + } + + @Override + public Object getHighLevelState(String stateID) + { + return highLevelStateHandler.getHighLevelState(stateID); } @Override @@ -44,39 +78,44 @@ public class DeserializedSubmodelComponent extends SubmodelComponent this.symbolRenderer = symbolRenderer; } + public void setHighLevelStateHandler(HighLevelStateHandler highLevelStateHandler) + { + this.highLevelStateHandler = highLevelStateHandler; + } + public ViewModelModifiable getSubmodelModifiable() { return submodelModifiable; } @Override - public void setSubmodelScale(double submodelScale) + public double getSubmodelScale() { - super.setSubmodelScale(submodelScale); + return super.getSubmodelScale(); } @Override - public void setSize(double width, double height) + public void setSubmodelScale(double submodelScale) { - super.setSize(width, height); + super.setSubmodelScale(submodelScale); } @Override - public Pin addSubmodelInterface(MovablePin supermodelPin) + public void setSize(double width, double height) { - return super.addSubmodelInterface(supermodelPin); + super.setSize(width, height); } @Override - public double getSubmodelScale() + public Map getSubmodelMovablePins() { - return super.getSubmodelScale(); + return super.getSubmodelMovablePins(); } @Override - public Map getSubmodelMovablePins() + public Pin addSubmodelInterface(MovablePin supermodelPin) { - return super.getSubmodelMovablePins(); + return super.addSubmodelInterface(supermodelPin); } @Override @@ -84,4 +123,6 @@ public class DeserializedSubmodelComponent extends SubmodelComponent { super.removeSubmodelInterface(name); } + + // TODO static initializer } \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java index 1c6a4846..23f8bcb8 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/IndirectGUIComponentCreator.java @@ -2,6 +2,7 @@ package net.mograsim.logic.model.serializing; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -11,6 +12,7 @@ import com.google.gson.JsonNull; import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.snippets.CodeSnippetSupplier; import net.mograsim.logic.model.util.JsonHandler; public class IndirectGUIComponentCreator @@ -94,9 +96,18 @@ public class IndirectGUIComponentCreator if (componentSupplier != null) return componentSupplier.create(model, params, name); } else - // we know id has to start with "file:" here - // because standardComponentIDs only contains strings starting with "class:" or "file:" - return SubmodelComponentDeserializer.create(model, resolvedID.substring(5), name); + // we know id has to start with "file:" here + // because standardComponentIDs only contains strings starting with "class:" or "file:" + if (params != null && !JsonNull.INSTANCE.equals(params)) + throw new IllegalArgumentException("Can't give params to a component deserialized from a JSON file"); + try + { + return SubmodelComponentSerializer.deserialize(model, resolvedID.substring(5), name, id, null); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } } throw new RuntimeException("Could not get component supplier for ID " + id); } diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentDeserializer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentDeserializer.java deleted file mode 100644 index a5e8793b..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentDeserializer.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.mograsim.logic.model.serializing; - -import java.io.IOException; -import java.util.Map; - -import net.mograsim.logic.model.model.ViewModelModifiable; -import net.mograsim.logic.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.model.wires.GUIWire; -import net.mograsim.logic.model.model.wires.MovablePin; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.InterfacePinParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerComponentParams; -import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams; - -/** - * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams} - */ -public final class SubmodelComponentDeserializer -{ - /** - * Like {@link #create(ViewModelModifiable, String, String)}, but using the default name. - */ - public static SubmodelComponent create(ViewModelModifiable model, String path) - { - return create(model, path, null); - } - - /** - * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams} located at the given path as a JSON file. The returned - * SubmodelComponent is a {@link DeserializedSubmodelComponent}. - * - * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent} - * @return A new SubmodelComponent, as described in the file located at the given path - */ - public static SubmodelComponent create(ViewModelModifiable model, String path, String name) - { - try - { - SubmodelComponentParams params = SubmodelComponentParams.readJson(path); - SubmodelComponent ret = create(model, params, name); - return ret; - } - catch (IOException e) - { - throw new RuntimeException("Failed to construct GUICustomComponent. Parameters were not found.", e); - } - } - - /** - * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent is a - * {@link DeserializedSubmodelComponent}. - * - * @param params The parameters describing the {@link SubmodelComponent} - * - * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams} - */ - public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params, String name) - { - DeserializedSubmodelComponent comp = createSubmodelComponent(model, params, name); - initSubmodel(comp, params.submodel); - return comp; - } - - private static DeserializedSubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params, - String name) - { - DeserializedSubmodelComponent comp = new DeserializedSubmodelComponent(model, name); - comp.setSubmodelScale(params.submodel.innerScale); - comp.setOutlineRenderer(CodeSnippetSupplier.outlineRendererSupplier.getSnippetSupplier(params.outlineRendererSnippetID).create(comp, - params.outlineRendererParams)); - comp.setSymbolRenderer(CodeSnippetSupplier.symbolRendererSupplier.getSnippetSupplier(params.symbolRendererSnippetID).create(comp, - params.symbolRendererParams)); - // TODO high level states - comp.setSize(params.width, params.height); - for (InterfacePinParams iPinParams : params.interfacePins) - comp.addSubmodelInterface( - new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y)); - return comp; - } - - @SuppressWarnings("unused") // GUIWire being created - private static void initSubmodel(DeserializedSubmodelComponent comp, SubmodelParameters params) - { - ViewModelModifiable submodelModifiable = comp.getSubmodelModifiable(); - Map componentsByName = submodelModifiable.getComponentsByName(); - GUIComponent[] components = new GUIComponent[params.subComps.length]; - for (int i = 0; i < components.length; i++) - { - InnerComponentParams cParams = params.subComps[i]; - components[i] = IndirectGUIComponentCreator.createComponent(submodelModifiable, cParams.id, cParams.params, cParams.name); - components[i].moveTo(cParams.pos.x, cParams.pos.y); - } - - for (int i = 0; i < params.innerWires.length; i++) - { - InnerWireParams innerWire = params.innerWires[i]; - new GUIWire(submodelModifiable, componentsByName.get(innerWire.pin1.compName).getPin(innerWire.pin1.pinName), - componentsByName.get(innerWire.pin2.compName).getPin(innerWire.pin2.pinName), innerWire.path); - } - } -} diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentParams.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentParams.java index afce226c..49edfd66 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentParams.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentParams.java @@ -25,6 +25,9 @@ public class SubmodelComponentParams public String symbolRendererSnippetID; public JsonElement symbolRendererParams; + public String highLevelStateHandlerSnippetID; + public JsonElement highLevelStateHandlerParams; + public static class InterfacePinParams { public Point location; diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentSerializer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentSerializer.java new file mode 100644 index 00000000..d98d4c98 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/SubmodelComponentSerializer.java @@ -0,0 +1,305 @@ +package net.mograsim.logic.model.serializing; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; + +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.mograsim.logic.model.model.ViewModelModifiable; +import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SimpleRectangularSubmodelComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.model.wires.GUIWire; +import net.mograsim.logic.model.model.wires.MovablePin; +import net.mograsim.logic.model.model.wires.Pin; +import net.mograsim.logic.model.serializing.SubmodelComponentParams.InterfacePinParams; +import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters; +import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerComponentParams; +import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams; +import net.mograsim.logic.model.serializing.SubmodelComponentParams.SubmodelParameters.InnerWireParams.InnerPinParams; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer.SimpleRectangularLikeParams; +import net.mograsim.logic.model.util.JsonHandler; + +/** + * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams} + * + * @author Fabian Stemmler + * @author Daniel Kirschten + */ +public final class SubmodelComponentSerializer +{ + // convenience methods + + /** + * Like {@link #deserialize(ViewModelModifiable, SubmodelComponentParams)}, but first reading the {@link SubmodelComponentParams} from + * the given file path. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, String sourcePath) throws IOException + { + return deserialize(model, JsonHandler.readJson(sourcePath, SubmodelComponentParams.class)); + } + + /** + * Like {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, JsonElement)}, but first reading the + * {@link SubmodelComponentParams} from the given file path. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, String sourcePath, String idForSerializingOverride, + JsonElement paramsForSerializingOverride) throws IOException + { + return deserialize(model, JsonHandler.readJson(sourcePath, SubmodelComponentParams.class), idForSerializingOverride, + paramsForSerializingOverride); + } + + /** + * Like {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String)}, but first reading the + * {@link SubmodelComponentParams} from the given file path. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, String sourcePath, String name) throws IOException + { + return deserialize(model, JsonHandler.readJson(sourcePath, SubmodelComponentParams.class), name); + } + + /** + * Like {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement)}, but first reading the + * {@link SubmodelComponentParams} from the given file path. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, String sourcePath, String name, String idForSerializingOverride, + JsonElement paramsForSerializingOverride) throws IOException + { + return deserialize(model, JsonHandler.readJson(sourcePath, SubmodelComponentParams.class), name, idForSerializingOverride, + paramsForSerializingOverride); + } + + /** + * {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement)} with no + * idForSerializingOverride set and using the default name. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, SubmodelComponentParams params) + { + return deserialize(model, params, null, null, null); + } + + /** + * {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement)} using the default name. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, SubmodelComponentParams params, String idForSerializingOverride, + JsonElement paramsForSerializingOverride) + { + return deserialize(model, params, null, idForSerializingOverride, paramsForSerializingOverride); + } + + /** + * {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement)} with no + * idForSerializingOverride set. + * + * @author Daniel Kirschten + */ + public static SubmodelComponent deserialize(ViewModelModifiable model, SubmodelComponentParams params, String name) + { + return deserialize(model, params, name, null, null); + } + + /** + * Like {@link #serialize(SubmodelComponent)}, but instead of returning the generated {@link SubmodelComponentParams} they are written + * to a file at the given path. + * + * @author Daniel Kirschten + */ + public static void serialize(SubmodelComponent comp, String targetPath) throws IOException + { + JsonHandler.writeJson(serialize(comp), targetPath); + } + + /** + * Like {@link #serialize(SubmodelComponent, Function)}, but instead of returning the generated {@link SubmodelComponentParams} they are + * written to a file at the given path. + * + * @author Daniel Kirschten + */ + public static void serialize(SubmodelComponent comp, Function getIdentifier, String targetPath) throws IOException + { + JsonHandler.writeJson(serialize(comp, getIdentifier), targetPath); + } + + /** + * {@link #serialize(SubmodelComponent, Function)} using "class:" concatenated with a component's complete (canonical) + * class name for the ID of a component. + * + * @author Daniel Kirschten + */ + public static SubmodelComponentParams serialize(SubmodelComponent comp) + { + return serialize(comp, c -> "class:" + c.getClass().getCanonicalName()); + } + + // "core" methods + /** + * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams} with the given name. + *

+ * When serializing a SubmodelComponent, it is undesired for every subcomponent to be serialized with its complete inner + * structure. Instead, these sub-SubmodelComponents should be serialized with the ID and params which were used to + * determine the SubmodelComponentParams defining the sub-SubmodelComponent. Because of this, it is possible + * to override the ID and params used in {@link #serialize(SubmodelComponent, Function) serialize(...)} to describe this subcomponent. + * See there for details. + * + * @author Fabian Stemmler + * @author Daniel Kirschten + */ + @SuppressWarnings("unused") // for GUIWire being created + public static SubmodelComponent deserialize(ViewModelModifiable model, SubmodelComponentParams params, String name, + String idForSerializingOverride, JsonElement paramsForSerializingOverride) + { + DeserializedSubmodelComponent comp = new DeserializedSubmodelComponent(model, name, idForSerializingOverride, + paramsForSerializingOverride); + comp.setSubmodelScale(params.submodel.innerScale); + comp.setOutlineRenderer(SubmodelComponentSnippetSuppliers.outlineRendererSupplier + .getSnippetSupplier(params.outlineRendererSnippetID).create(comp, params.outlineRendererParams)); + comp.setSymbolRenderer(SubmodelComponentSnippetSuppliers.symbolRendererSupplier.getSnippetSupplier(params.symbolRendererSnippetID) + .create(comp, params.symbolRendererParams)); + comp.setHighLevelStateHandler(SubmodelComponentSnippetSuppliers.highLevelStateHandlerSupplier + .getSnippetSupplier(params.highLevelStateHandlerSnippetID).create(comp, params.highLevelStateHandlerParams)); + comp.setSize(params.width, params.height); + for (InterfacePinParams iPinParams : params.interfacePins) + comp.addSubmodelInterface( + new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y)); + SubmodelParameters submodelParams = params.submodel; + ViewModelModifiable submodelModifiable = comp.getSubmodelModifiable(); + Map componentsByName = submodelModifiable.getComponentsByName(); + GUIComponent[] components = new GUIComponent[submodelParams.subComps.length]; + for (int i = 0; i < components.length; i++) + { + InnerComponentParams cParams = submodelParams.subComps[i]; + components[i] = IndirectGUIComponentCreator.createComponent(submodelModifiable, cParams.id, cParams.params, cParams.name); + components[i].moveTo(cParams.pos.x, cParams.pos.y); + } + + for (int i = 0; i < submodelParams.innerWires.length; i++) + { + InnerWireParams innerWire = submodelParams.innerWires[i]; + new GUIWire(submodelModifiable, componentsByName.get(innerWire.pin1.compName).getPin(innerWire.pin1.pinName), + componentsByName.get(innerWire.pin2.compName).getPin(innerWire.pin2.pinName), innerWire.path); + } + return comp; + } + + /** + * Returns {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}.
+ * Subcomponents are serialized in the following way:
+ * If a subcomponent is a SubmodelComponent which has been deserialized, and it has an + * {@link DeserializedSubmodelComponent#idForSerializingOverride idForSerializingOverride} set (e.g. non-null; see + * {@link #deserialize(ViewModelModifiable, SubmodelComponentParams, String, String, JsonElement) deserialize(...)}), this ID and the + * component's {@link DeserializedSubmodelComponent#paramsForSerializingOverride paramsForSerializingOverride} are written.
+ * If this case doesn't apply (e.g. if the subcomponent is not a SubmodelComponent; or it is a + * SubmodelComponent, but hasn't been deserialized; or it has no + * {@link DeserializedSubmodelComponent#idForSerializingOverride idForSerializingOverride} set), the ID returned by + * getIdentifier and the params obtained by {@link GUIComponent#getParamsForSerializing() getParams()} are written. + * + * @author Fabian Stemmler + * @author Daniel Kirschten + */ + public static SubmodelComponentParams serialize(SubmodelComponent comp, Function getIdentifier) + { + SubmodelParameters submodelParams = new SubmodelParameters(); + submodelParams.innerScale = comp.getSubmodelScale(); + + Map components = new HashMap<>(comp.submodel.getComponentsByName()); + components.remove(SubmodelComponent.SUBMODEL_INTERFACE_NAME); + InnerComponentParams[] comps = new InnerComponentParams[components.size()]; + int i1 = 0; + for (GUIComponent innerComp : components.values()) + { + InnerComponentParams innerParams = new InnerComponentParams(); + comps[i1] = innerParams; + innerParams.pos = new Point(innerComp.getPosX(), innerComp.getPosY()); + DeserializedSubmodelComponent innerCompCasted; + if (innerComp instanceof DeserializedSubmodelComponent + && (innerCompCasted = (DeserializedSubmodelComponent) innerComp).idForSerializingOverride != null) + { + innerParams.id = innerCompCasted.idForSerializingOverride; + innerParams.params = innerCompCasted.paramsForSerializingOverride; + } else + { + innerParams.id = getIdentifier.apply(innerComp); + innerParams.params = innerComp.getParamsForSerializing(); + } + innerParams.name = innerComp.name; + i1++; + } + submodelParams.subComps = comps; + + List wireList = comp.submodel.getWires(); + InnerWireParams wires[] = new InnerWireParams[wireList.size()]; + i1 = 0; + for (GUIWire wire : wireList) + { + InnerWireParams inner = new InnerWireParams(); + wires[i1] = inner; + InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams(); + + pin1Params.pinName = wire.getPin1().name; + pin1Params.compName = wire.getPin1().component.name; + pin2Params.pinName = wire.getPin2().name; + pin2Params.compName = wire.getPin2().component.name; + inner.pin1 = pin1Params; + inner.pin2 = pin2Params; + inner.path = wire.getPath(); + i1++; + } + submodelParams.innerWires = wires; + + SubmodelComponentParams params = new SubmodelComponentParams(); + params.submodel = submodelParams; + + params.width = comp.getWidth(); + params.height = comp.getHeight(); + + InterfacePinParams[] iPins = new InterfacePinParams[comp.getPins().size()]; + int i = 0; + for (Pin p : comp.getPins().values()) + { + InterfacePinParams iPinParams = new InterfacePinParams(); + iPins[i] = iPinParams; + iPinParams.location = p.getRelPos(); + iPinParams.name = p.name; + iPinParams.logicWidth = p.logicWidth; + i++; + } + params.interfacePins = iPins; + + // TODO does this code belong here? + if (comp instanceof SimpleRectangularSubmodelComponent) + { + SimpleRectangularSubmodelComponent compCasted = (SimpleRectangularSubmodelComponent) comp; + + SimpleRectangularLikeParams symbolRendererParams = new SimpleRectangularLikeParams(); + symbolRendererParams.centerText = compCasted.label; + symbolRendererParams.centerTextHeight = SimpleRectangularSubmodelComponent.labelFontHeight; + symbolRendererParams.horizontalComponentCenter = compCasted.getWidth() / 2; + symbolRendererParams.pinLabelHeight = SimpleRectangularSubmodelComponent.pinNameFontHeight; + symbolRendererParams.pinLabelMargin = SimpleRectangularSubmodelComponent.pinNameMargin; + + params.symbolRendererSnippetID = "simpleRectangularLike"; + params.symbolRendererParams = new Gson().toJsonTree(symbolRendererParams); + } + + return params; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/HighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/HighLevelStateHandler.java deleted file mode 100644 index f20b6642..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/HighLevelStateHandler.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets; - -import net.mograsim.logic.model.model.components.GUIComponent; - -public interface HighLevelStateHandler -{ - /** - * Sets the given high-level state to the given value.
- * A high level state ID consists of parts separated by dots ('.').
- * The last part (the part after the last dot) is called "atomic high level state ID". The parts before that part are called - * "subcomponent ID"s.
- * If there is no dot in a high level state ID, the whole high level state ID is called atomic.
- * Note that subcomponent IDs don't have to correspond to actual subcomponents. For example, a RAM component may supply subcomponent IDs - * "c0000", "c0001" ... "cFFFF" without actually having a subcomponent for each cell. It also is allowed to delegate an atomic high - * level state ID to a subcomponent. - * - * @see #getHighLevelState(String) - * @see GUIComponent#setHighLevelState(String, Object) - * - * @author Daniel Kirschten - */ - public void setHighLevelState(String stateID, Object newState); - - /** - * Gets the current value of the given high-level state.
- * See {@link #setHighLevelState(String, Object)} for an explanation of high-level state IDs. - * - * @see #setHighLevelState(String, Object) - * @see GUIComponent#getHighLevelState(String) - * - * @author Daniel Kirschten - */ - public Object getHighLevelState(String stateID); -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/Renderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/Renderer.java deleted file mode 100644 index 140780b7..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/Renderer.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets; - -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; - -public interface Renderer -{ - public void render(GeneralGC gc, Rectangle visibleRegion); -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/SnippetSupplier.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/SnippetSupplier.java deleted file mode 100644 index a2b71b5d..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/SnippetSupplier.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets; - -import java.util.function.BiFunction; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; - -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; - -public interface SnippetSupplier -{ - public Class

getParamClass(); - - public S create(SubmodelComponent component, P params); - - public default S create(SubmodelComponent component, JsonElement params) - { - return create(component, new Gson().fromJson(params, getParamClass())); - } - - public static SnippetSupplier create(Class

paramClass, BiFunction supplier) - { - return new SnippetSupplier<>() - { - @Override - public Class

getParamClass() - { - return paramClass; - } - - @Override - public S create(SubmodelComponent component, P params) - { - return supplier.apply(component, params); - } - }; - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java deleted file mode 100644 index eb08addc..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets.highlevelstatehandlers; - -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.serializing.CodeSnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.HighLevelStateHandler; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; - -public class DefaultHighLevelStateHandler implements HighLevelStateHandler -{ - @SuppressWarnings("unused") // we don't need the component; and params are always null - public DefaultHighLevelStateHandler(SubmodelComponent component, Void params) - { - // nothing to do here - } - - @Override - public void setHighLevelState(String stateID, Object newState) - { - throw new IllegalArgumentException("No high level state with ID " + stateID); - } - - @Override - public Object getHighLevelState(String stateID) - { - throw new IllegalArgumentException("No high level state with ID " + stateID); - } - - static - { - CodeSnippetSupplier.highLevelStateHandlerSupplier.setSnippetSupplier(DefaultHighLevelStateHandler.class.getCanonicalName(), - SnippetSupplier.create(Void.class, DefaultHighLevelStateHandler::new)); - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/outlinerenderers/DefaultOutlineRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/outlinerenderers/DefaultOutlineRenderer.java deleted file mode 100644 index 31528643..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/outlinerenderers/DefaultOutlineRenderer.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets.outlinerenderers; - -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -import net.mograsim.logic.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.serializing.CodeSnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; -import net.mograsim.preferences.ColorDefinition; -import net.mograsim.preferences.ColorManager; -import net.mograsim.preferences.Preferences; - -public class DefaultOutlineRenderer implements Renderer -{ - private final GUIComponent component; - - public DefaultOutlineRenderer(SubmodelComponent component, @SuppressWarnings("unused") Void params) - { - this.component = component; - } - - @Override - public void render(GeneralGC gc, Rectangle visibleRegion) - { - ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.foreground"); - if (fg != null) - gc.setForeground(ColorManager.current().toColor(fg)); - gc.drawRectangle(component.getBounds()); - } - - static - { - CodeSnippetSupplier.outlineRendererSupplier.setSnippetSupplier(DefaultOutlineRenderer.class.getCanonicalName(), - SnippetSupplier.create(Void.class, DefaultOutlineRenderer::new)); - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/CenteredTextSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/CenteredTextSymbolRenderer.java deleted file mode 100644 index 9ccfa9c7..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/CenteredTextSymbolRenderer.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets.symbolrenderers; - -import net.haspamelodica.swt.helper.gcs.GeneralGC; -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.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.serializing.CodeSnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; -import net.mograsim.preferences.ColorDefinition; -import net.mograsim.preferences.ColorManager; -import net.mograsim.preferences.Preferences; - -/** - * Renders a text ("text") with a given font height ("height") in the center of the component. - * - * @author Daniel Kirschten - */ -public class CenteredTextSymbolRenderer implements Renderer -{ - private final GUIComponent component; - private final CenteredTextParams params; - - public CenteredTextSymbolRenderer(SubmodelComponent component, CenteredTextParams params) - { - this.component = component; - this.params = params; - - } - - @Override - public void render(GeneralGC gc, Rectangle visibleRegion) - { - Font oldFont = gc.getFont(); - gc.setFont(new Font(oldFont.getName(), params.fontHeight, oldFont.getStyle())); - ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text"); - if (fg != null) - gc.setForeground(ColorManager.current().toColor(fg)); - Point idSize = gc.textExtent(params.text); - Rectangle bounds = component.getBounds(); - gc.drawText(params.text, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true); - gc.setFont(oldFont); - } - - public static class CenteredTextParams - { - public String text; - public double fontHeight; - } - - static - { - CodeSnippetSupplier.symbolRendererSupplier.setSnippetSupplier(CenteredTextSymbolRenderer.class.getCanonicalName(), - SnippetSupplier.create(CenteredTextParams.class, CenteredTextSymbolRenderer::new)); - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/DefaultSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/DefaultSymbolRenderer.java deleted file mode 100644 index e6beadfe..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/DefaultSymbolRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets.symbolrenderers; - -import net.haspamelodica.swt.helper.gcs.GeneralGC; -import net.haspamelodica.swt.helper.swtobjectwrappers.Point; -import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; -import net.mograsim.logic.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.serializing.CodeSnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; -import net.mograsim.preferences.ColorDefinition; -import net.mograsim.preferences.ColorManager; -import net.mograsim.preferences.Preferences; - -public class DefaultSymbolRenderer implements Renderer -{ - private static final String id = ""; - - private final GUIComponent component; - - public DefaultSymbolRenderer(SubmodelComponent component, @SuppressWarnings("unused") Void params) - { - this.component = component; - } - - @Override - public void render(GeneralGC gc, Rectangle visibleRegion) - { - ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text"); - if (fg != null) - gc.setForeground(ColorManager.current().toColor(fg)); - Point idSize = gc.textExtent(id); - Rectangle bounds = component.getBounds(); - gc.drawText(id, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true); - } - - static - { - CodeSnippetSupplier.symbolRendererSupplier.setSnippetSupplier(DefaultSymbolRenderer.class.getCanonicalName(), - SnippetSupplier.create(Void.class, DefaultSymbolRenderer::new)); - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java deleted file mode 100644 index 30ab4bca..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.mograsim.logic.model.serializing.snippets.symbolrenderers; - -import java.util.Map.Entry; - -import org.eclipse.swt.graphics.Color; - -import net.haspamelodica.swt.helper.gcs.GeneralGC; -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.model.model.components.GUIComponent; -import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; -import net.mograsim.logic.model.model.wires.Pin; -import net.mograsim.logic.model.serializing.CodeSnippetSupplier; -import net.mograsim.logic.model.serializing.snippets.Renderer; -import net.mograsim.logic.model.serializing.snippets.SnippetSupplier; -import net.mograsim.preferences.Preferences; - -/** - * Renders a text ("centerText") with a given font height ("centerTextHeight") in the center of the component and - * draws a label for each pin with a given font height ("pinLabelHeight"). The labels of pins to the left of a given x - * coordinate ("horizontalComponentCenter") are drawn to the right of the respective pin; labels of pins to the right are drawn - * left. A margin ("pinLabelMargin") is applied for pin label drawing. - * - * @author Daniel Kirschten - */ -public class SimpleRectangularLikeSymbolRenderer implements Renderer -{ - private final GUIComponent component; - private final SimpleRectangularLikeParams params; - - public SimpleRectangularLikeSymbolRenderer(SubmodelComponent component, SimpleRectangularLikeParams params) - { - this.component = component; - this.params = params; - } - - @Override - public void render(GeneralGC gc, Rectangle visibleRegion) - { - double posX = component.getPosX(); - double posY = component.getPosY(); - double width = component.getWidth(); - double height = component.getHeight(); - - Font oldFont = gc.getFont(); - gc.setFont(new Font(oldFont.getName(), params.centerTextHeight, oldFont.getStyle())); - Point textExtent = gc.textExtent(params.centerText); - Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text"); - if (textColor != null) - gc.setForeground(textColor); - gc.drawText(params.centerText, posX + (width - textExtent.x) / 2, posY + (height - textExtent.y) / 2, true); - gc.setFont(new Font(oldFont.getName(), params.pinLabelHeight, oldFont.getStyle())); - for (Entry pinEntry : component.getPins().entrySet()) - { - String pinName = pinEntry.getKey(); - Pin pin = pinEntry.getValue(); - double pinX = pin.getRelX(); - double pinY = posY + pin.getRelY(); - textExtent = gc.textExtent(pinName); - gc.drawText(pinName, - posX + pinX + (pinX > params.horizontalComponentCenter ? -textExtent.x - params.pinLabelMargin : params.pinLabelMargin), - pinY - textExtent.y / 2, true); - } - gc.setFont(oldFont); - } - - public static class SimpleRectangularLikeParams - { - public String centerText; - public double centerTextHeight; - public double horizontalComponentCenter; - public double pinLabelHeight; - public double pinLabelMargin; - } - - static - { - CodeSnippetSupplier.symbolRendererSupplier.setSnippetSupplier(SimpleRectangularLikeSymbolRenderer.class.getCanonicalName(), - SnippetSupplier.create(SimpleRectangularLikeParams.class, SimpleRectangularLikeSymbolRenderer::new)); - } -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/standardSnippetIDMapping.json b/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/standardSnippetIDMapping.json deleted file mode 100644 index db79c5fe..00000000 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/serializing/standardSnippetIDMapping.json +++ /dev/null @@ -1,9 +0,0 @@ -mograsim version: 0.1.3 -{ - "standardOutlineRendererSuppliers": {}, - "standardSymbolRendererSuppliers": { - "CenteredTextSymbolRenderer": "net.mograsim.logic.model.serializing.snippets.symbolrenderers.CenteredTextSymbolRenderer", - "SimpleRectangularLikeSymbolRenderer": "net.mograsim.logic.model.serializing.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer" - }, - "standardHighLevelStateHandlerSuppliers": {} -} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/CodeSnippetSupplier.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/CodeSnippetSupplier.java new file mode 100644 index 00000000..86b57656 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/CodeSnippetSupplier.java @@ -0,0 +1,70 @@ +package net.mograsim.logic.model.snippets; + +import java.util.HashMap; +import java.util.Map; + +public class CodeSnippetSupplier +{ + private final Map standardSnippetIDClassNames = new HashMap<>(); + private final Map> snippetSuppliersForClassNames = new HashMap<>(); + private final SnippetDefinintion defaultSnippetSupplier; + + public CodeSnippetSupplier(SnippetDefinintion defaultSnippetSupplier) + { + this.defaultSnippetSupplier = defaultSnippetSupplier; + } + + public void addStandardSnippetID(String standardSnippetID, String associatedSnippetClassName) + { + standardSnippetIDClassNames.put(standardSnippetID, associatedSnippetClassName); + } + + public void setSnippetSupplier(String id, SnippetDefinintion snippetSupplier) + { + snippetSuppliersForClassNames.put(id, snippetSupplier); + } + + // TODO report errors + public SnippetDefinintion getSnippetSupplier(String id) + { + if (id != null) + { + String snippetClassName; + if (id.startsWith("class:")) + snippetClassName = id.substring(6); + else + snippetClassName = standardSnippetIDClassNames.get(id); + if (snippetClassName != null) + { + tryLoadSnippetClass(snippetClassName); + SnippetDefinintion snippetSupplier = snippetSuppliersForClassNames.get(snippetClassName); + if (snippetSupplier != null) + return snippetSupplier; + } + System.err.println("Couldn't load snippet " + id + "; using default"); + } + if (defaultSnippetSupplier == null) + throw new IllegalArgumentException("No default snippet set"); + return defaultSnippetSupplier; + } + + // static helpers + + private static void tryLoadSnippetClass(String snippetClassName) + { + tryInvokeStaticInitializer(snippetClassName, "Error getting snippet class: %s: %s\n"); + } + + public static void tryInvokeStaticInitializer(String className, String errorMessageFormat) + { + try + { + Class.forName(className, true, CodeSnippetSupplier.class.getClassLoader()); + } + catch (ClassNotFoundException e) + { + System.err.printf(errorMessageFormat, className, "ClassNotFoundException thrown: " + e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/HighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/HighLevelStateHandler.java new file mode 100644 index 00000000..74f01d0f --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/HighLevelStateHandler.java @@ -0,0 +1,40 @@ +package net.mograsim.logic.model.snippets; + +import net.mograsim.logic.model.model.components.GUIComponent; + +/** + * A high level state ID consists of parts separated by dots ('.').
+ * The last part (the part after the last dot) is called "atomic high level state ID". The parts before that part are called "subcomponent + * ID"s.
+ * If there is no dot in a high level state ID, the whole high level state ID is called atomic.
+ * Note that subcomponent IDs don't have to correspond to actual subcomponents. For example, a RAM component may supply subcomponent IDs + * "c0000", "c0001" ... "cFFFF" without actually having a subcomponent for each cell. It also is allowed to delegate an atomic high level + * state ID to a subcomponent. + * + * @author Daniel Kirschten + */ +public interface HighLevelStateHandler +{ + /** + * Gets the current value of the given high-level state.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @see #setHighLevelState(String, Object) + * @see GUIComponent#getHighLevelState(String) + * + * @author Daniel Kirschten + */ + public Object getHighLevelState(String stateID); + + /** + * Sets the given high-level state to the given value.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @see #getHighLevelState(String) + * @see GUIComponent#setHighLevelState(String, Object) + * + * @author Daniel Kirschten + */ + public void setHighLevelState(String stateID, Object newState); + +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/Renderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/Renderer.java new file mode 100644 index 00000000..45a2c5e8 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/Renderer.java @@ -0,0 +1,9 @@ +package net.mograsim.logic.model.snippets; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; + +public interface Renderer +{ + public void render(GeneralGC gc, Rectangle visibleRegion); +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SnippetDefinintion.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SnippetDefinintion.java new file mode 100644 index 00000000..77e715cd --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SnippetDefinintion.java @@ -0,0 +1,36 @@ +package net.mograsim.logic.model.snippets; + +import java.util.function.BiFunction; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; + +public interface SnippetDefinintion +{ + public Class

getParamClass(); + + public S create(C context, P params); + + public default S create(C context, JsonElement params) + { + return create(context, new Gson().fromJson(params, getParamClass())); + } + + public static SnippetDefinintion create(Class

paramClass, BiFunction supplier) + { + return new SnippetDefinintion<>() + { + @Override + public Class

getParamClass() + { + return paramClass; + } + + @Override + public S create(C context, P params) + { + return supplier.apply(context, params); + } + }; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SubmodelComponentSnippetSuppliers.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SubmodelComponentSnippetSuppliers.java new file mode 100644 index 00000000..ff6e5549 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/SubmodelComponentSnippetSuppliers.java @@ -0,0 +1,55 @@ +package net.mograsim.logic.model.snippets; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.DefaultHighLevelStateHandler; +import net.mograsim.logic.model.snippets.outlinerenderers.DefaultOutlineRenderer; +import net.mograsim.logic.model.snippets.symbolrenderers.DefaultSymbolRenderer; +import net.mograsim.logic.model.util.JsonHandler; + +public class SubmodelComponentSnippetSuppliers +{ + public static final CodeSnippetSupplier symbolRendererSupplier; + public static final CodeSnippetSupplier outlineRendererSupplier; + public static final CodeSnippetSupplier highLevelStateHandlerSupplier; + + static + { + symbolRendererSupplier = new CodeSnippetSupplier<>(SnippetDefinintion.create(Void.class, DefaultSymbolRenderer::new)); + outlineRendererSupplier = new CodeSnippetSupplier<>(SnippetDefinintion.create(Void.class, DefaultOutlineRenderer::new)); + highLevelStateHandlerSupplier = new CodeSnippetSupplier<>(SnippetDefinintion.create(Void.class, DefaultHighLevelStateHandler::new)); + } + + static + { + try (InputStream s = SubmodelComponentSnippetSuppliers.class.getResourceAsStream("./standardSnippetIDMapping.json")) + { + if (s == null) + throw new IOException("Resource not found"); + SnippetIDClassNames tmp = JsonHandler.readJson(s, SnippetIDClassNames.class); + tmp.standardOutlineRendererSuppliers.forEach(outlineRendererSupplier::addStandardSnippetID); + tmp.standardSymbolRendererSuppliers.forEach(symbolRendererSupplier::addStandardSnippetID); + tmp.standardHighLevelStateHandlerSuppliers.forEach(highLevelStateHandlerSupplier::addStandardSnippetID); + } + catch (Exception e) + { + System.err.println("Failed to initialize standard snippet ID mapping:"); + e.printStackTrace(); + } + } + + private static class SnippetIDClassNames + { + public Map standardOutlineRendererSuppliers; + public Map standardSymbolRendererSuppliers; + public Map standardHighLevelStateHandlerSuppliers; + } + + private SubmodelComponentSnippetSuppliers() + { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java new file mode 100644 index 00000000..37c32d07 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/DefaultHighLevelStateHandler.java @@ -0,0 +1,34 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers; + +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.HighLevelStateHandler; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; + +public class DefaultHighLevelStateHandler implements HighLevelStateHandler +{ + @SuppressWarnings("unused") // we don't need the component; and params are always null + public DefaultHighLevelStateHandler(SubmodelComponent component, Void params) + { + // nothing to do here + } + + @Override + public Object getHighLevelState(String stateID) + { + throw new IllegalArgumentException("No high level state with ID " + stateID); + } + + @Override + public void setHighLevelState(String stateID, Object newState) + { + throw new IllegalArgumentException("No high level state with ID " + stateID); + } + + static + { + SubmodelComponentSnippetSuppliers.highLevelStateHandlerSupplier.setSnippetSupplier( + DefaultHighLevelStateHandler.class.getCanonicalName(), + SnippetDefinintion.create(Void.class, DefaultHighLevelStateHandler::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/HighLevelStateHandlerContext.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/HighLevelStateHandlerContext.java new file mode 100644 index 00000000..ba3ae198 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/HighLevelStateHandlerContext.java @@ -0,0 +1,15 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard; + +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; + +public class HighLevelStateHandlerContext +{ + public final SubmodelComponent component; + public final String stateID; + + public HighLevelStateHandlerContext(SubmodelComponent component, String stateID) + { + this.component = component; + this.stateID = stateID; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandler.java new file mode 100644 index 00000000..1c3ac62c --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandler.java @@ -0,0 +1,154 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.HighLevelStateHandler; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler.AtomicHighLevelStateHandlerParams; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler.SubcomponentHighLevelStateHandlerParams; + +public class StandardHighLevelStateHandler implements HighLevelStateHandler +{ + private final SubmodelComponent component; + private final Map subcomponentHighLevelStateHandlers; + private final Map atomicHighLevelStateHandlers; + + public StandardHighLevelStateHandler(SubmodelComponent component) + { + this(component, null); + } + + public StandardHighLevelStateHandler(SubmodelComponent component, StandardHighLevelStateHandlerParams params) + { + this.component = component; + this.subcomponentHighLevelStateHandlers = new HashMap<>(); + this.atomicHighLevelStateHandlers = new HashMap<>(); + if (params != null) + { + params.subcomponentHighLevelStates.forEach(this::addSubcomponentHighLevelState); + params.atomicHighLevelStates.forEach(this::addAtomicHighLevelState); + } + } + + public SubcomponentHighLevelStateHandler addSubcomponentHighLevelState(String subcomponentStateID, + SubcomponentHighLevelStateHandlerParams handlerParams) + { + return addSubcomponentHighLevelState(subcomponentStateID, + StandardHighLevelStateHandlerSnippetSuppliers.subcomponentHandlerSupplier.getSnippetSupplier(handlerParams.id)::create, + handlerParams.params); + } + + public H addSubcomponentHighLevelState(String subcomponentStateID, + BiFunction handlerConstructor, P handlerParams) + { + return addSubcomponentHighLevelState(subcomponentStateID, c -> handlerConstructor.apply(c, handlerParams)); + } + + public H addSubcomponentHighLevelState(String subcomponentStateID, + Function handlerConstructor) + { + HighLevelStateHandlerContext context = new HighLevelStateHandlerContext(component, subcomponentStateID); + H handler = handlerConstructor.apply(context); + addSubcomponentHighLevelState(subcomponentStateID, handler); + return handler; + } + + public void addSubcomponentHighLevelState(String subcomponentStateID, SubcomponentHighLevelStateHandler handler) + { + checkHighLevelStateIDPart(subcomponentStateID); + subcomponentHighLevelStateHandlers.put(subcomponentStateID, handler); + } + + public AtomicHighLevelStateHandler addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandlerParams handlerParams) + { + return addAtomicHighLevelState(atomicStateID, + StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.getSnippetSupplier(handlerParams.id)::create, + handlerParams.params); + } + + public H addAtomicHighLevelState(String subcomponentStateID, + BiFunction handlerConstructor, P handlerParams) + { + return addAtomicHighLevelState(subcomponentStateID, c -> handlerConstructor.apply(c, handlerParams)); + } + + public H addAtomicHighLevelState(String subcomponentStateID, + Function handlerConstructor) + { + HighLevelStateHandlerContext context = new HighLevelStateHandlerContext(component, subcomponentStateID); + H handler = handlerConstructor.apply(context); + addAtomicHighLevelState(subcomponentStateID, handler); + return handler; + } + + public void addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandler handler) + { + checkHighLevelStateIDPart(atomicStateID); + atomicHighLevelStateHandlers.put(atomicStateID, handler); + } + + private static void checkHighLevelStateIDPart(String stateIDPart) + { + if (stateIDPart.indexOf('.') != -1) + throw new IllegalArgumentException("Illegal high level state ID part (contains dot): " + stateIDPart); + } + + @Override + public Object getHighLevelState(String stateID) + { + int indexOfDot = stateID.indexOf('.'); + if (indexOfDot == -1) + { + AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID); + if (handler != null) + return handler.getHighLevelState(); + } else + { + SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot)); + if (handler != null) + return handler.getHighLevelState(stateID.substring(indexOfDot + 1)); + } + throw new IllegalArgumentException("No high level state with ID " + stateID); + } + + @Override + public void setHighLevelState(String stateID, Object newState) + { + int indexOfDot = stateID.indexOf('.'); + if (indexOfDot == -1) + { + AtomicHighLevelStateHandler handler = atomicHighLevelStateHandlers.get(stateID); + if (handler != null) + handler.setHighLevelState(newState); + else + throw new IllegalArgumentException("No high level state with ID " + stateID); + } else + { + SubcomponentHighLevelStateHandler handler = subcomponentHighLevelStateHandlers.get(stateID.substring(0, indexOfDot)); + if (handler != null) + handler.setHighLevelState(stateID.substring(indexOfDot + 1), newState); + else + throw new IllegalArgumentException("No high level state with ID " + stateID); + } + } + + public static class StandardHighLevelStateHandlerParams + { + public Map subcomponentHighLevelStates; + public Map atomicHighLevelStates; + } + + static + { + SubmodelComponentSnippetSuppliers.highLevelStateHandlerSupplier.setSnippetSupplier( + StandardHighLevelStateHandler.class.getCanonicalName(), + SnippetDefinintion.create(StandardHighLevelStateHandlerParams.class, StandardHighLevelStateHandler::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandlerSnippetSuppliers.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandlerSnippetSuppliers.java new file mode 100644 index 00000000..51629207 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandlerSnippetSuppliers.java @@ -0,0 +1,51 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import net.mograsim.logic.model.snippets.CodeSnippetSupplier; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.AtomicHighLevelStateHandler; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.SubcomponentHighLevelStateHandler; +import net.mograsim.logic.model.util.JsonHandler; + +public class StandardHighLevelStateHandlerSnippetSuppliers +{ + public static final CodeSnippetSupplier atomicHandlerSupplier; + public static final CodeSnippetSupplier subcomponentHandlerSupplier; + + static + { + atomicHandlerSupplier = new CodeSnippetSupplier<>(null); + subcomponentHandlerSupplier = new CodeSnippetSupplier<>(null); + } + + static + { + // TODO update standardSnippetIDMapping.json + try (InputStream s = StandardHighLevelStateHandlerSnippetSuppliers.class.getResourceAsStream("./standardSnippetIDMapping.json")) + { + if (s == null) + throw new IOException("Resource not found"); + SnippetIDClassNames tmp = JsonHandler.readJson(s, SnippetIDClassNames.class); + tmp.standardSubcomponentHandlerSuppliers.forEach(subcomponentHandlerSupplier::addStandardSnippetID); + tmp.standardAtomicHandlerSuppliers.forEach(atomicHandlerSupplier::addStandardSnippetID); + } + catch (Exception e) + { + System.err.println("Failed to initialize standard snippet ID mapping: "); + e.printStackTrace(); + } + } + + private static class SnippetIDClassNames + { + public Map standardSubcomponentHandlerSuppliers; + public Map standardAtomicHandlerSuppliers; + } + + private StandardHighLevelStateHandlerSnippetSuppliers() + { + throw new UnsupportedOperationException(); + } +} diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/AtomicHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/AtomicHighLevelStateHandler.java new file mode 100644 index 00000000..dedc6d58 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/AtomicHighLevelStateHandler.java @@ -0,0 +1,30 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic; + +import com.google.gson.JsonObject; + +import net.mograsim.logic.model.snippets.HighLevelStateHandler; + +public interface AtomicHighLevelStateHandler +{ + /** + * Gets the current value of the atomic high level state represented by this AtomicHighLevelStateHandler.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @author Daniel Kirschten + */ + public Object getHighLevelState(); + + /** + * Sets the atomic high level state represented by this AtomicHighLevelStateHandler to the given value.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @author Daniel Kirschten + */ + public void setHighLevelState(Object newState); + + public static class AtomicHighLevelStateHandlerParams + { + public String id; + public JsonObject params; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/BitVectorSplittingAtomicHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/BitVectorSplittingAtomicHighLevelStateHandler.java new file mode 100644 index 00000000..4b1139be --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/BitVectorSplittingAtomicHighLevelStateHandler.java @@ -0,0 +1,90 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic; + +import java.util.ArrayList; +import java.util.List; + +import net.mograsim.logic.core.types.BitVector; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext; + +public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler +{ + private SubmodelComponent component; + private final List vectorPartTargets; + private final List vectorPartLengthes; + + public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context) + { + this(context, null); + } + + public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, + BitVectorSplittingAtomicHighLevelStateHandlerParams params) + { + this.component = context.component; + this.vectorPartTargets = new ArrayList<>(); + this.vectorPartLengthes = new ArrayList<>(); + if (params != null) + setVectorParts(params.vectorPartTargets, params.vectorPartLengthes); + } + + public void set(List targets, List lengthes) + { + setVectorParts(targets, lengthes); + } + + public void addVectorPart(String target, int length) + { + vectorPartTargets.add(target); + vectorPartLengthes.add(length); + } + + public void clearVectorParts() + { + vectorPartTargets.clear(); + vectorPartLengthes.clear(); + } + + private void setVectorParts(List targets, List lengthes) + { + clearVectorParts(); + if (targets.size() != lengthes.size()) + throw new IllegalArgumentException("Targets list and lenghtes list have different sizes"); + vectorPartTargets.addAll(targets); + vectorPartLengthes.addAll(lengthes); + } + + @Override + public Object getHighLevelState() + { + BitVector result = BitVector.of(); + for (int partIndex = 0; partIndex < vectorPartTargets.size(); partIndex++) + { + BitVector vectorPart = (BitVector) component.getHighLevelState(vectorPartTargets.get(partIndex)); + if (vectorPart.length() != vectorPartLengthes.get(partIndex)) + throw new IllegalArgumentException( + "Illegal vector part length: " + vectorPart.length() + "; expected " + vectorPartLengthes.get(partIndex)); + result = result.concat(vectorPart);// TODO is the bit order correct? + } + return result; + } + + @Override + public void setHighLevelState(Object newState) + { + BitVector newStateCasted = (BitVector) newState; + for (int partIndex = 0, bitIndex = 0; partIndex < vectorPartTargets.size(); partIndex++) + { + int vectorPartLength = vectorPartLengthes.get(partIndex); + BitVector vectorPart = newStateCasted.subVector(bitIndex, vectorPartLength);// TODO is the bit order correct? + component.setHighLevelState(vectorPartTargets.get(partIndex), vectorPart); + bitIndex += vectorPartLength; + } + } + + public static class BitVectorSplittingAtomicHighLevelStateHandlerParams + { + public List vectorPartTargets; + public List vectorPartLengthes; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/DelegatingAtomicHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/DelegatingAtomicHighLevelStateHandler.java new file mode 100644 index 00000000..0ed207f4 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/DelegatingAtomicHighLevelStateHandler.java @@ -0,0 +1,70 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic; + +import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext; + +public class DelegatingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler +{ + private final SubmodelComponent parentComponent; + private GUIComponent delegateTarget; + private String subStateID; + + public DelegatingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context) + { + this(context, null); + } + + public DelegatingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context, DelegatingAtomicHighLevelStateHandlerParams params) + { + this.parentComponent = context.component; + if (params != null) + { + // TODO document this + if (params.delegateTarget == null) + setDelegateTarget(parentComponent); + else + setDelegateTarget(parentComponent.submodel.getComponentsByName().get(params.delegateTarget)); + setSubStateID(params.subStateID); + } + } + + public void set(GUIComponent delegateTarget, String subStateID) + { + setDelegateTarget(delegateTarget); + setSubStateID(subStateID); + } + + public void setDelegateTarget(GUIComponent delegateTarget) + { + if (delegateTarget == null) + this.delegateTarget = parentComponent; + else if (!parentComponent.submodel.getComponentsByName().containsValue(delegateTarget)) + throw new IllegalArgumentException( + "Can only set components belonging to the submodel of the parent component of this handler as the delegate target"); + this.delegateTarget = delegateTarget; + } + + public void setSubStateID(String subStateID) + { + this.subStateID = subStateID; + } + + @Override + public Object getHighLevelState() + { + return delegateTarget.getHighLevelState(subStateID); + } + + @Override + public void setHighLevelState(Object newState) + { + delegateTarget.setHighLevelState(subStateID, newState); + } + + public static class DelegatingAtomicHighLevelStateHandlerParams + { + public String delegateTarget; + public String subStateID; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/standardSnippetIDMapping.json b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/standardSnippetIDMapping.json new file mode 100644 index 00000000..de32e706 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/standardSnippetIDMapping.json @@ -0,0 +1,10 @@ +mograsim version: 0.1.3 +{ + "standardSubcomponentHandlerSuppliers": { + "delegating": "net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent.DelegatingSubcomponentHighLevelStateHandler" + }, + "standardAtomicHandlerSuppliers": { + "delegating": "net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.DelegatingAtomicHighLevelStateHandler" + "bitVectorSplitting": "net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic.BitVectorSplittingAtomicHighLevelStateHandler" + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/DelegatingSubcomponentHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/DelegatingSubcomponentHighLevelStateHandler.java new file mode 100644 index 00000000..79ec244d --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/DelegatingSubcomponentHighLevelStateHandler.java @@ -0,0 +1,76 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent; + +import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.HighLevelStateHandlerContext; + +public class DelegatingSubcomponentHighLevelStateHandler implements SubcomponentHighLevelStateHandler +{ + private final SubmodelComponent parentComponent; + private GUIComponent delegateTarget; + private String prefix; + + public DelegatingSubcomponentHighLevelStateHandler(HighLevelStateHandlerContext context) + { + this(context, null); + } + + public DelegatingSubcomponentHighLevelStateHandler(HighLevelStateHandlerContext context, + DelegatingSubcomponentHighLevelStateHandlerParams params) + { + this.parentComponent = context.component; + if (params != null) + { + // TODO document this + if (params.delegateTarget == null) + setDelegateTarget(parentComponent); + else + this.delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget); + setPrefix(prefix); + } + } + + public void set(GUIComponent delegateTarget, String prefix) + { + setDelegateTarget(delegateTarget); + setPrefix(prefix); + } + + public void setDelegateTarget(GUIComponent delegateTarget) + { + if (delegateTarget == null) + this.delegateTarget = parentComponent; + else if (!parentComponent.submodel.getComponentsByName().containsValue(delegateTarget)) + throw new IllegalArgumentException( + "Can only set components belonging to the submodel of the parent component of this handler as the delegate target"); + this.delegateTarget = delegateTarget; + } + + public void setPrefix(String prefix) + { + this.prefix = prefix; + } + + @Override + public Object getHighLevelState(String subStateID) + { + return delegateTarget.getHighLevelState(getDelegateTargetHighLevelStateID(subStateID)); + } + + @Override + public void setHighLevelState(String subStateID, Object newState) + { + delegateTarget.setHighLevelState(getDelegateTargetHighLevelStateID(subStateID), newState); + } + + private String getDelegateTargetHighLevelStateID(String subStateID) + { + return prefix == null ? subStateID : prefix + '.' + subStateID; + } + + public static class DelegatingSubcomponentHighLevelStateHandlerParams + { + public String delegateTarget; + public String prefix; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/SubcomponentHighLevelStateHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/SubcomponentHighLevelStateHandler.java new file mode 100644 index 00000000..412bd191 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/SubcomponentHighLevelStateHandler.java @@ -0,0 +1,30 @@ +package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.subcomponent; + +import com.google.gson.JsonObject; + +import net.mograsim.logic.model.snippets.HighLevelStateHandler; + +public interface SubcomponentHighLevelStateHandler +{ + /** + * Gets the current value of the given high level state of the subcomponent represented by this SubcomponentHighLevelStateHandler.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @author Daniel Kirschten + */ + public Object getHighLevelState(String subStateID); + + /** + * Sets the given high level state of the subcomponent represented by this SubcomponentHighLevelStateHandler to the given value.
+ * See {@link HighLevelStateHandler} for an explanation of high-level state IDs. + * + * @author Daniel Kirschten + */ + public void setHighLevelState(String subStateID, Object newState); + + public static class SubcomponentHighLevelStateHandlerParams + { + public String id; + public JsonObject params; + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/outlinerenderers/DefaultOutlineRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/outlinerenderers/DefaultOutlineRenderer.java new file mode 100644 index 00000000..f7841dd6 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/outlinerenderers/DefaultOutlineRenderer.java @@ -0,0 +1,37 @@ +package net.mograsim.logic.model.snippets.outlinerenderers; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; +import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.preferences.ColorDefinition; +import net.mograsim.preferences.ColorManager; +import net.mograsim.preferences.Preferences; + +public class DefaultOutlineRenderer implements Renderer +{ + private final GUIComponent component; + + public DefaultOutlineRenderer(SubmodelComponent component, @SuppressWarnings("unused") Void params) + { + this.component = component; + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.foreground"); + if (fg != null) + gc.setForeground(ColorManager.current().toColor(fg)); + gc.drawRectangle(component.getBounds()); + } + + static + { + SubmodelComponentSnippetSuppliers.outlineRendererSupplier.setSnippetSupplier(DefaultOutlineRenderer.class.getCanonicalName(), + SnippetDefinintion.create(Void.class, DefaultOutlineRenderer::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/standardSnippetIDMapping.json b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/standardSnippetIDMapping.json new file mode 100644 index 00000000..68757796 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/standardSnippetIDMapping.json @@ -0,0 +1,11 @@ +mograsim version: 0.1.3 +{ + "standardOutlineRendererSuppliers": {}, + "standardSymbolRendererSuppliers": { + "centeredText": "net.mograsim.logic.model.snippets.symbolrenderers.CenteredTextSymbolRenderer", + "simpleRectangularLike": "net.mograsim.logic.model.snippets.symbolrenderers.SimpleRectangularLikeSymbolRenderer" + }, + "standardHighLevelStateHandlerSuppliers": { + "standard": "net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandler" + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/CenteredTextSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/CenteredTextSymbolRenderer.java new file mode 100644 index 00000000..e1a68508 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/CenteredTextSymbolRenderer.java @@ -0,0 +1,58 @@ +package net.mograsim.logic.model.snippets.symbolrenderers; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +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.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.preferences.ColorDefinition; +import net.mograsim.preferences.ColorManager; +import net.mograsim.preferences.Preferences; + +/** + * Renders a text ("text") with a given font height ("height") in the center of the component. + * + * @author Daniel Kirschten + */ +public class CenteredTextSymbolRenderer implements Renderer +{ + private final GUIComponent component; + private final CenteredTextParams params; + + public CenteredTextSymbolRenderer(SubmodelComponent component, CenteredTextParams params) + { + this.component = component; + this.params = params; + + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + Font oldFont = gc.getFont(); + gc.setFont(new Font(oldFont.getName(), params.fontHeight, oldFont.getStyle())); + ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text"); + if (fg != null) + gc.setForeground(ColorManager.current().toColor(fg)); + Point idSize = gc.textExtent(params.text); + Rectangle bounds = component.getBounds(); + gc.drawText(params.text, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true); + gc.setFont(oldFont); + } + + public static class CenteredTextParams + { + public String text; + public double fontHeight; + } + + static + { + SubmodelComponentSnippetSuppliers.symbolRendererSupplier.setSnippetSupplier(CenteredTextSymbolRenderer.class.getCanonicalName(), + SnippetDefinintion.create(CenteredTextParams.class, CenteredTextSymbolRenderer::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/DefaultSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/DefaultSymbolRenderer.java new file mode 100644 index 00000000..3faf0b91 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/DefaultSymbolRenderer.java @@ -0,0 +1,42 @@ +package net.mograsim.logic.model.snippets.symbolrenderers; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +import net.haspamelodica.swt.helper.swtobjectwrappers.Point; +import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; +import net.mograsim.logic.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.preferences.ColorDefinition; +import net.mograsim.preferences.ColorManager; +import net.mograsim.preferences.Preferences; + +public class DefaultSymbolRenderer implements Renderer +{ + private static final String id = ""; + + private final GUIComponent component; + + public DefaultSymbolRenderer(SubmodelComponent component, @SuppressWarnings("unused") Void params) + { + this.component = component; + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + ColorDefinition fg = Preferences.current().getColorDefinition("net.mograsim.logic.ui.color.text"); + if (fg != null) + gc.setForeground(ColorManager.current().toColor(fg)); + Point idSize = gc.textExtent(id); + Rectangle bounds = component.getBounds(); + gc.drawText(id, bounds.x + (bounds.width - idSize.x) / 2, bounds.y + (bounds.height - idSize.y) / 2, true); + } + + static + { + SubmodelComponentSnippetSuppliers.symbolRendererSupplier.setSnippetSupplier(DefaultSymbolRenderer.class.getCanonicalName(), + SnippetDefinintion.create(Void.class, DefaultSymbolRenderer::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java new file mode 100644 index 00000000..d3173851 --- /dev/null +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/SimpleRectangularLikeSymbolRenderer.java @@ -0,0 +1,83 @@ +package net.mograsim.logic.model.snippets.symbolrenderers; + +import java.util.Map.Entry; + +import org.eclipse.swt.graphics.Color; + +import net.haspamelodica.swt.helper.gcs.GeneralGC; +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.model.model.components.GUIComponent; +import net.mograsim.logic.model.model.components.submodels.SubmodelComponent; +import net.mograsim.logic.model.model.wires.Pin; +import net.mograsim.logic.model.snippets.Renderer; +import net.mograsim.logic.model.snippets.SnippetDefinintion; +import net.mograsim.logic.model.snippets.SubmodelComponentSnippetSuppliers; +import net.mograsim.preferences.Preferences; + +/** + * Renders a text ("centerText") with a given font height ("centerTextHeight") in the center of the component and + * draws a label for each pin with a given font height ("pinLabelHeight"). The labels of pins to the left of a given x + * coordinate ("horizontalComponentCenter") are drawn to the right of the respective pin; labels of pins to the right are drawn + * left. A margin ("pinLabelMargin") is applied for pin label drawing. + * + * @author Daniel Kirschten + */ +public class SimpleRectangularLikeSymbolRenderer implements Renderer +{ + private final GUIComponent component; + private final SimpleRectangularLikeParams params; + + public SimpleRectangularLikeSymbolRenderer(SubmodelComponent component, SimpleRectangularLikeParams params) + { + this.component = component; + this.params = params; + } + + @Override + public void render(GeneralGC gc, Rectangle visibleRegion) + { + double posX = component.getPosX(); + double posY = component.getPosY(); + double width = component.getWidth(); + double height = component.getHeight(); + + Font oldFont = gc.getFont(); + gc.setFont(new Font(oldFont.getName(), params.centerTextHeight, oldFont.getStyle())); + Point textExtent = gc.textExtent(params.centerText); + Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text"); + if (textColor != null) + gc.setForeground(textColor); + gc.drawText(params.centerText, posX + (width - textExtent.x) / 2, posY + (height - textExtent.y) / 2, true); + gc.setFont(new Font(oldFont.getName(), params.pinLabelHeight, oldFont.getStyle())); + for (Entry pinEntry : component.getPins().entrySet()) + { + String pinName = pinEntry.getKey(); + Pin pin = pinEntry.getValue(); + double pinX = pin.getRelX(); + double pinY = posY + pin.getRelY(); + textExtent = gc.textExtent(pinName); + gc.drawText(pinName, + posX + pinX + (pinX > params.horizontalComponentCenter ? -textExtent.x - params.pinLabelMargin : params.pinLabelMargin), + pinY - textExtent.y / 2, true); + } + gc.setFont(oldFont); + } + + public static class SimpleRectangularLikeParams + { + public String centerText; + public double centerTextHeight; + public double horizontalComponentCenter; + public double pinLabelHeight; + public double pinLabelMargin; + } + + static + { + SubmodelComponentSnippetSuppliers.symbolRendererSupplier.setSnippetSupplier( + SimpleRectangularLikeSymbolRenderer.class.getCanonicalName(), + SnippetDefinintion.create(SimpleRectangularLikeParams.class, SimpleRectangularLikeSymbolRenderer::new)); + } +} \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/util/JsonHandler.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/util/JsonHandler.java index 9cd9e8cc..2ada2e72 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/util/JsonHandler.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/util/JsonHandler.java @@ -13,6 +13,7 @@ import com.google.gson.GsonBuilder; public class JsonHandler { + // TODO: write versions differently private static Gson parser = new GsonBuilder().setPrettyPrinting().create(); public static T readJson(String path, Class type) throws IOException