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)
{
}
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
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)
{
_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
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)
{
_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
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)
{
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)
{
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
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);
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)
{
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)
{
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
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
public class GUIAm2901 extends SimpleRectangularSubmodelComponent
{
- private GUIram4 ram;
- private GUIAm2901QReg qreg;
public GUIAm2901(ViewModelModifiable model)
{
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);
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
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)
{
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)
{
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
/**
* 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
*/
/**
* 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
*/
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;
*/
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.
*/
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;
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
/**
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)
return params;
}
- public List<GUIComponent> getComponents()
- {
- return submodel.getComponents();
- }
-
- public List<GUIWire> getWires()
- {
- return submodel.getWires();
- }
-
// operations no longer supported
@Override