From 574918bb58faa3c617911ed4f629f90066668364 Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Sun, 30 Jun 2019 15:13:31 +0200 Subject: [PATCH] Restructured high level state access --- .../components/mi/nandbased/GUI_rsLatch.java | 15 +- .../model/components/mi/nandbased/GUIdff.java | 13 +- .../components/mi/nandbased/GUIdlatch.java | 13 +- .../components/mi/nandbased/GUIdlatch4.java | 17 +- .../components/mi/nandbased/GUIram2.java | 60 ++---- .../components/mi/nandbased/GUIram4.java | 193 ++++++++---------- .../mi/nandbased/am2901/GUIAm2901.java | 56 +---- .../mi/nandbased/am2901/GUIAm2901QReg.java | 17 +- .../ui/model/components/GUIComponent.java | 10 +- .../model/components/SubmodelComponent.java | 181 +++++++++++++++- 10 files changed, 336 insertions(+), 239 deletions(-) diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUI_rsLatch.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUI_rsLatch.java index a7f80256..1ee2a1ef 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUI_rsLatch.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUI_rsLatch.java @@ -50,10 +50,12 @@ public class GUI_rsLatch extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, cp2, nand1.getPin("B"), new Point(65, 42.5), new Point(5, 42.5), new Point(5, 22.5)); wireQ = new GUIWire(submodelModifiable, cp1, Q, new Point(35, 17.5), new Point(35, 7.5), new Point(65, 7.5), new Point(65, 12.5)); wire_Q = new GUIWire(submodelModifiable, cp2, _Q, new Point[0]); + + addAtomicHighLevelStateID("q"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -74,22 +76,23 @@ public class GUI_rsLatch extends SimpleRectangularSubmodelComponent } break; default: - super.setHighLevelState(stateID, newState); - break; + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { case "q": if (wireQ.hasLogicModelBinding()) - return wireQ.getWireValues().getBit(0).join(wire_Q.getWireValues().getBit(0).not()); + return wireQ.getWireValues().getBit(0); return null; default: - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdff.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdff.java index 8f183dcc..dc53862b 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdff.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdff.java @@ -63,10 +63,12 @@ public class GUIdff extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, cp4, nand2.getPin("A"), new Point(100, 65)); new GUIWire(submodelModifiable, _rsLatch2.getPin("Q"), Q); new GUIWire(submodelModifiable, _rsLatch2.getPin("_Q"), _Q); + + addAtomicHighLevelStateID("q"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -74,20 +76,21 @@ public class GUIdff extends SimpleRectangularSubmodelComponent _rsLatch.setHighLevelState("q", newState); break; default: - super.setHighLevelState(stateID, newState); - break; + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { case "q": return _rsLatch.getHighLevelState("q"); default: - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch.java index 009e6f05..95a3e3fc 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch.java @@ -52,10 +52,12 @@ public class GUIdlatch extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, nand2.getPin("Y"), _rsLatch.getPin("_R"), new Point(40, 37.5), new Point(40, 22.5)); new GUIWire(submodelModifiable, _rsLatch.getPin("Q"), Q, new Point[0]); new GUIWire(submodelModifiable, _rsLatch.getPin("_Q"), _Q); + + addAtomicHighLevelStateID("q"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -63,20 +65,21 @@ public class GUIdlatch extends SimpleRectangularSubmodelComponent _rsLatch.setHighLevelState("q", newState); break; default: - super.setHighLevelState(stateID, newState); - break; + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { case "q": return _rsLatch.getHighLevelState("q"); default: - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch4.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch4.java index 8da90e16..bda25ba3 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch4.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch4.java @@ -70,10 +70,16 @@ public class GUIdlatch4 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, dlatch2.getPin("Q"), Q2, new Point[0]); 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"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -97,13 +103,13 @@ public class GUIdlatch4 extends SimpleRectangularSubmodelComponent setHighLevelState("q4", newStateCasted.getBit(3)); break; default: - super.setHighLevelState(stateID, newState); - break; + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { @@ -122,7 +128,8 @@ public class GUIdlatch4 extends SimpleRectangularSubmodelComponent Bit q4 = (Bit) getHighLevelState("q4"); return BitVector.of(q1, q2, q3, q4); default: - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram2.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram2.java index 3e4d013d..7c084efb 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram2.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram2.java @@ -49,10 +49,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); + cell00 = new GUIdlatch4 (submodelModifiable); + cell01 = new GUIdlatch4 (submodelModifiable); + cell10 = new GUIdlatch4 (submodelModifiable); + cell11 = new GUIdlatch4 (submodelModifiable); GUIand41 andA00 = new GUIand41 (submodelModifiable); GUIandor414 andorA01 = new GUIandor414(submodelModifiable); GUIandor414 andorA10 = new GUIandor414(submodelModifiable); @@ -277,10 +277,16 @@ public class GUIram2 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, andorB11.getPin("Y3"), QB3 , new Point(180, 760), new Point(180, 890), new Point(335, 890), new Point(335, 650)); 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"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -292,33 +298,13 @@ public class GUIram2 extends SimpleRectangularSubmodelComponent setHighLevelState("c11.q", newStateCasted.subVector(12, 16)); break; default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - switch (stateID.substring(0, indexOfDot)) - { - case "c00": - cell00.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - case "c01": - cell01.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - case "c10": - cell10.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - case "c11": - cell11.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - default: - super.setHighLevelState(stateID, newState); - break; - } - else - super.setHighLevelState(stateID, newState); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { @@ -329,22 +315,8 @@ public class GUIram2 extends SimpleRectangularSubmodelComponent BitVector q11 = (BitVector) getHighLevelState("c11.q"); return q00.concat(q01).concat(q10).concat(q11); default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - switch (stateID.substring(0, indexOfDot)) - { - case "c00": - return cell00.getHighLevelState(stateID.substring(indexOfDot + 1)); - case "c01": - return cell01.getHighLevelState(stateID.substring(indexOfDot + 1)); - case "c10": - return cell10.getHighLevelState(stateID.substring(indexOfDot + 1)); - case "c11": - return cell11.getHighLevelState(stateID.substring(indexOfDot + 1)); - default: - return super.getHighLevelState(stateID); - } - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram4.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram4.java index d982f018..c34c50c2 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram4.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram4.java @@ -285,128 +285,111 @@ public class GUIram4 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, andorA11.getPin("Y3"), QA3 , new Point(200, 760), new Point(200, 890), new Point(320, 890), new Point(320, 250)); 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("c10", cell01); + addHighLevelStateSubcomponentID("c01", cell10); + addHighLevelStateSubcomponentID("c11", cell11); + addAtomicHighLevelStateID("q"); } @Override - public Object getHighLevelState(String stateID) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { case "q": - BitVector q0000 = (BitVector) getHighLevelState("c0000.q"); - BitVector q0001 = (BitVector) getHighLevelState("c0001.q"); - BitVector q0010 = (BitVector) getHighLevelState("c0010.q"); - BitVector q0011 = (BitVector) getHighLevelState("c0011.q"); - BitVector q0100 = (BitVector) getHighLevelState("c0100.q"); - BitVector q0101 = (BitVector) getHighLevelState("c0101.q"); - BitVector q0110 = (BitVector) getHighLevelState("c0110.q"); - BitVector q0111 = (BitVector) getHighLevelState("c0111.q"); - BitVector q1000 = (BitVector) getHighLevelState("c1000.q"); - BitVector q1001 = (BitVector) getHighLevelState("c1001.q"); - BitVector q1010 = (BitVector) getHighLevelState("c1010.q"); - BitVector q1011 = (BitVector) getHighLevelState("c1011.q"); - BitVector q1100 = (BitVector) getHighLevelState("c1100.q"); - BitVector q1101 = (BitVector) getHighLevelState("c1101.q"); - BitVector q1110 = (BitVector) getHighLevelState("c1110.q"); - BitVector q1111 = (BitVector) getHighLevelState("c1111.q"); - return q0000.concat(q0001).concat(q0010).concat(q0011).concat(q0100).concat(q0101).concat(q0110).concat(q0111).concat(q1000) - .concat(q1001).concat(q1010).concat(q1011).concat(q1100).concat(q1101).concat(q1110).concat(q1111); + BitVector newStateCasted = (BitVector) newState; + setHighLevelState("c00.q", newStateCasted.subVector(0, 16)); + setHighLevelState("c01.q", newStateCasted.subVector(16, 32)); + setHighLevelState("c11.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) + { + switch (subcomponentID) + { + case "c0000": + case "c0001": + case "c0010": + case "c0011": + cell00.setHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID, newState); + break; + case "c1000": + case "c1001": + case "c1010": + case "c1011": + cell01.setHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID, newState); + break; + case "c0100": + case "c0101": + case "c0110": + case "c0111": + cell10.setHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID, newState); + break; + case "c1100": + case "c1101": + case "c1110": + case "c1111": + cell11.setHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID, newState); + break; default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - { - String cellID = stateID.substring(0, indexOfDot); - switch (cellID) - { - case "c0000": - case "c0001": - case "c0010": - case "c0011": - return cell00.getHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot)); - case "c0100": - case "c0101": - case "c0110": - case "c0111": - return cell01.getHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot)); - case "c1000": - case "c1001": - case "c1010": - case "c1011": - return cell10.getHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot)); - case "c1100": - case "c1101": - case "c1110": - case "c1111": - return cell11.getHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot)); - default: - return super.getHighLevelState(stateID); - } - } - return super.getHighLevelState(stateID); + super.setSubcomponentHighLevelState(subcomponentID, subcomponentHighLevelStateID, newState); + break; } } @Override - public void setHighLevelState(String stateID, Object newState) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { case "q": - BitVector newStateCasted = (BitVector) newState; - setHighLevelState("c0000.q", newStateCasted.subVector(0, 4)); - setHighLevelState("c0001.q", newStateCasted.subVector(4, 8)); - setHighLevelState("c0010.q", newStateCasted.subVector(8, 12)); - setHighLevelState("c0011.q", newStateCasted.subVector(12, 16)); - setHighLevelState("c0100.q", newStateCasted.subVector(16, 20)); - setHighLevelState("c0101.q", newStateCasted.subVector(20, 24)); - setHighLevelState("c0110.q", newStateCasted.subVector(24, 28)); - setHighLevelState("c0111.q", newStateCasted.subVector(28, 32)); - setHighLevelState("c1000.q", newStateCasted.subVector(32, 36)); - setHighLevelState("c1001.q", newStateCasted.subVector(36, 40)); - setHighLevelState("c1010.q", newStateCasted.subVector(40, 44)); - setHighLevelState("c1011.q", newStateCasted.subVector(44, 48)); - setHighLevelState("c1100.q", newStateCasted.subVector(48, 52)); - setHighLevelState("c1101.q", newStateCasted.subVector(52, 56)); - setHighLevelState("c1110.q", newStateCasted.subVector(56, 60)); - setHighLevelState("c1111.q", newStateCasted.subVector(60, 64)); - break; + 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); + } + } + + @Override + protected Object getSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID) + { + switch (subcomponentID) + { + case "c0000": + case "c0001": + case "c0010": + case "c0011": + return cell00.getHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID); + case "c0100": + case "c0101": + case "c0110": + case "c0111": + return cell01.getHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID); + case "c1000": + case "c1001": + case "c1010": + case "c1011": + return cell10.getHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID); + case "c1100": + case "c1101": + case "c1110": + case "c1111": + return cell11.getHighLevelState('c' + subcomponentID.substring(3, 5) + "." + subcomponentHighLevelStateID); default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - { - String cellID = stateID.substring(0, indexOfDot); - switch (cellID) - { - case "c0000": - case "c0001": - case "c0010": - case "c0011": - cell00.setHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot), newState); - break; - case "c0100": - case "c0101": - case "c0110": - case "c0111": - cell01.setHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot), newState); - break; - case "c1000": - case "c1001": - case "c1010": - case "c1011": - cell10.setHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot), newState); - break; - case "c1100": - case "c1101": - case "c1110": - case "c1111": - cell11.setHighLevelState('c' + cellID.substring(3, 5) + stateID.substring(indexOfDot), newState); - break; - default: - super.setHighLevelState(stateID, newState); - break; - } - } else - super.setHighLevelState(stateID, newState); + return super.getSubcomponentHighLevelState(subcomponentID, subcomponentHighLevelStateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901.java index b589e67e..fa3eabba 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901.java @@ -16,8 +16,6 @@ import net.mograsim.logic.ui.model.wires.WireCrossPoint; public class GUIAm2901 extends SimpleRectangularSubmodelComponent { - private GUIram4 ram; - private GUIAm2901QReg qreg; public GUIAm2901(ViewModelModifiable model) { @@ -79,12 +77,12 @@ public class GUIAm2901 extends SimpleRectangularSubmodelComponent GUIAm2901ALUInclSourceDecodeInclFunctionDecode alu = new GUIAm2901ALUInclSourceDecodeInclFunctionDecode(submodelModifiable); GUIor4 Fneq0 = new GUIor4(submodelModifiable); GUINandGate notFneq0 = new GUINandGate(submodelModifiable, 1); - ram = new GUIram4(submodelModifiable); + GUIram4 ram = new GUIram4(submodelModifiable); GUIdlatch4 QAlatch = new GUIdlatch4(submodelModifiable); GUIdlatch4 QBlatch = new GUIdlatch4(submodelModifiable); GUIsel3_4 ramDsel = new GUIsel3_4(submodelModifiable); GUIsel3_4 qregDsel = new GUIsel3_4(submodelModifiable); - qreg = new GUIAm2901QReg(submodelModifiable); + GUIAm2901QReg qreg = new GUIAm2901QReg(submodelModifiable); WireCrossPoint cpC1 = new WireCrossPoint(submodelModifiable, 1); WireCrossPoint cpC2 = new WireCrossPoint(submodelModifiable, 1); @@ -342,54 +340,8 @@ public class GUIAm2901 extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, cpFneq0, notFneq0.getPin("A"), new Point(315, 445)); new GUIWire(submodelModifiable, cpFneq0, notFneq0.getPin("B"), new Point(315, 455)); new GUIWire(submodelModifiable, notFneq0.getPin("Y"), Feq0, new Point[0]); - } - @Override - public void setHighLevelState(String stateID, Object newState) - { - switch (stateID) - { - default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - { - switch (stateID.substring(0, indexOfDot)) - { - case "regs": - ram.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - case "qreg": - qreg.setHighLevelState(stateID.substring(indexOfDot + 1), newState); - break; - default: - super.setHighLevelState(stateID, newState); - break; - } - } else - super.setHighLevelState(stateID, newState); - } - } - - @Override - public Object getHighLevelState(String stateID) - { - switch (stateID) - { - default: - int indexOfDot = stateID.indexOf('.'); - if (indexOfDot != -1) - { - switch (stateID.substring(0, indexOfDot)) - { - case "regs": - return ram.getHighLevelState(stateID.substring(indexOfDot + 1)); - case "qreg": - return qreg.getHighLevelState(stateID.substring(indexOfDot + 1)); - default: - return super.getHighLevelState(stateID); - } - } - return super.getHighLevelState(stateID); - } + addHighLevelStateSubcomponentID("regs", ram); + addHighLevelStateSubcomponentID("qreg", qreg); } } \ No newline at end of file diff --git a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901QReg.java b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901QReg.java index eaec5016..9a8ca31c 100644 --- a/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901QReg.java +++ b/net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901QReg.java @@ -78,10 +78,16 @@ public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent new GUIWire(submodelModifiable, dff2.getPin("Q"), Q2, new Point[0]); 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"); } @Override - public void setHighLevelState(String stateID, Object newState) + public void setAtomicHighLevelState(String stateID, Object newState) { switch (stateID) { @@ -105,13 +111,13 @@ public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent setHighLevelState("q4", newStateCasted.getBit(3)); break; default: - super.setHighLevelState(stateID, newState); - break; + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } @Override - public Object getHighLevelState(String stateID) + public Object getAtomicHighLevelState(String stateID) { switch (stateID) { @@ -130,7 +136,8 @@ public class GUIAm2901QReg extends SimpleRectangularSubmodelComponent Bit q4 = (Bit) getHighLevelState("q4"); return BitVector.of(q1, q2, q3, q4); default: - return super.getHighLevelState(stateID); + // should not happen because we tell SubmodelComponent to only allow these state IDs. + throw new IllegalStateException("Illegal atomic state ID: " + stateID); } } } \ No newline at end of file diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java index f961cafc..a80c15c4 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java @@ -142,7 +142,13 @@ public abstract class GUIComponent /** * Sets the given high-level state to the given value.
- * TODO more documentation! + * 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 for an atomic high level state + * ID to be delegated to a subcomponent. * * @author Daniel Kirschten */ @@ -154,7 +160,7 @@ public abstract class GUIComponent /** * Gets the current value of the given high-level state.
- * TODO more documentation! + * See {@link #setHighLevelState(String, Object)} for an explanation of high-level state IDs. * * @author Daniel Kirschten */ diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java index 3db44fdf..94dc693c 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java @@ -2,10 +2,12 @@ package net.mograsim.logic.ui.model.components; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import net.haspamelodica.swt.helper.gcs.GCConfig; import net.haspamelodica.swt.helper.gcs.GeneralGC; @@ -67,6 +69,15 @@ 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. */ @@ -101,6 +112,9 @@ public abstract class SubmodelComponent extends GUIComponent this.supermodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins); this.submodelInterface = new SubmodelInterface(submodelModifiable); + this.highLevelAtomicStates = new HashSet<>(); + this.subcomponentsByHighLevelStateSubcomponentID = new HashMap<>(); + this.submodelScale = 1; this.maxVisibleRegionFillRatioForAlpha0 = 0.4; this.minVisibleRegionFillRatioForAlpha1 = 0.8; @@ -247,6 +261,153 @@ 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 /** @@ -303,8 +464,18 @@ public abstract class SubmodelComponent extends GUIComponent renderOutline(gc, visibleRegion); } + /** + * Render the outline of this {@link SubmodelComponent}, e.g. the graphical elements that should stay visible if the submodel is drawn. + * + * @author Daniel Kirschten + */ protected abstract void renderOutline(GeneralGC gc, Rectangle visibleRegion); + /** + * Render the symbol of this {@link SubmodelComponent}, e.g. the things that should be hidden if the submodel is drawn. + * + * @author Daniel Kirschten + */ protected abstract void renderSymbol(GeneralGC gc, Rectangle visibleRegion); private static double map(double val, double valMin, double valMax, double mapMin, double mapMax) @@ -397,16 +568,6 @@ public abstract class SubmodelComponent extends GUIComponent return params; } - public List getComponents() - { - return submodel.getComponents(); - } - - public List getWires() - { - return submodel.getWires(); - } - // operations no longer supported @Override -- 2.17.1