Restructured high level state access
authorDaniel Kirschten <daniel.kirschten@gmx.de>
Sun, 30 Jun 2019 13:13:31 +0000 (15:13 +0200)
committerDaniel Kirschten <daniel.kirschten@gmx.de>
Sun, 30 Jun 2019 13:13:31 +0000 (15:13 +0200)
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUI_rsLatch.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdff.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIdlatch4.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram2.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/GUIram4.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901.java
net.mograsim.logic.ui.am2900/src/net/mograsim/logic/ui/model/components/mi/nandbased/am2901/GUIAm2901QReg.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/SubmodelComponent.java

index a7f8025..1ee2a1e 100644 (file)
@@ -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
index 8f183dc..dc53862 100644 (file)
@@ -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
index 009e6f0..95a3e3f 100644 (file)
@@ -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
index 8da90e1..bda25ba 100644 (file)
@@ -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
index 3e4d013..7c084ef 100644 (file)
@@ -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
index d982f01..c34c50c 100644 (file)
@@ -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
index b589e67..fa3eabb 100644 (file)
@@ -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
index eaec501..9a8ca31 100644 (file)
@@ -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
index f961caf..a80c15c 100644 (file)
@@ -142,7 +142,13 @@ public abstract class GUIComponent
 
        /**
         * Sets the given high-level state to the given value. <br>
-        * TODO more documentation!
+        * A high level state ID consists of parts separated by dots ('.').<br>
+        * 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.<br>
+        * If there is no dot in a high level state ID, the whole high level state ID is called atomic.<br>
+        * 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. <br>
-        * TODO more documentation!
+        * See {@link #setHighLevelState(String, Object)} for an explanation of high-level state IDs.
         * 
         * @author Daniel Kirschten
         */
index 3db44fd..94dc693 100644 (file)
@@ -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<String> highLevelAtomicStates;
+       /**
+        * A map of high level state subcomponent IDs to the {@link GUIComponent} high level state access requests are delegated to.
+        */
+       private final Map<String, GUIComponent> 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. <br>
+        * Note that this method does not affect whether {@link #setSubcomponentHighLevelState(String, String, Object)
+        * set}/{@link #getSubcomponentHighLevelState(String, String)} will be called. <br>
+        * 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. <br>
+        * Note that this method does not affect whether {@link #setSubcomponentHighLevelState(String, String, Object)
+        * set}/{@link #getSubcomponentHighLevelState(String, String)} will be called.<br>
+        * 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. <br>
+        * 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. <br>
+        * 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.<br>
+        * 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. <br>
+        * 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. <br>
+        * 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. <br>
+        * 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<GUIComponent> getComponents()
-       {
-               return submodel.getComponents();
-       }
-
-       public List<GUIWire> getWires()
-       {
-               return submodel.getWires();
-       }
-
        // operations no longer supported
 
        @Override