import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
-import net.mograsim.logic.ui.model.components.GUIComponentCreator;
-import net.mograsim.logic.ui.model.components.GUICustomComponentCreator;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
-import net.mograsim.logic.ui.model.components.SubmodelComponent;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIfulladder;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIhalfadder;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
+import net.mograsim.logic.ui.serializing.IndirectGUIComponentCreator;
+import net.mograsim.logic.ui.serializing.SubmodelComponentDeserializer;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
public class JsonExample
{
public static void mappingTest(ViewModelModifiable model)
{
- GUIComponentCreator.create(model, "GUIAm2901", new HashMap<String, Object>());
+ IndirectGUIComponentCreator.create(model, "GUIAm2901", new HashMap<String, Object>());
}
private static class TestComponent extends SimpleRectangularSubmodelComponent
super(model, 1, "Test");
setSubmodelScale(.4);
setInputPins("Input pin #0");
- GUICustomComponentCreator.create(submodelModifiable, "HalfAdder.json");
+ SubmodelComponentDeserializer.create(submodelModifiable, "HalfAdder.json");
}
}
{
TestComponent t = new TestComponent(model);
t.calculateParams().writeJson("Test.json");
- SubmodelComponent c = GUICustomComponentCreator.create(model, "Test.json");
+ SubmodelComponent c = SubmodelComponentDeserializer.create(model, "Test.json");
c.moveTo(0, 50);
}
e.printStackTrace();
}
- GUICustomComponentCreator.create(model, p);
+ SubmodelComponentDeserializer.create(model, p);
}
@SuppressWarnings("unused") // for GUIWires being created
e.printStackTrace();
}
- SimpleRectangularSubmodelComponent adder = (SimpleRectangularSubmodelComponent) GUICustomComponentCreator.create(model,
+ SimpleRectangularSubmodelComponent adder = (SimpleRectangularSubmodelComponent) SubmodelComponentDeserializer.create(model,
"FullAdder.json");
GUIManualSwitch swA = new GUIManualSwitch(model);
new GUIWire(model, adder.getPin("Y"), bdY.getInputPin());
new GUIWire(model, adder.getPin("Z"), bdZ.getInputPin());
- SubmodelComponent adder2 = GUICustomComponentCreator.create(model, pC);
+ SubmodelComponent adder2 = SubmodelComponentDeserializer.create(model, pC);
swA = new GUIManualSwitch(model);
swA.moveTo(0, 70);
import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
import net.mograsim.logic.ui.model.components.mi.nandbased.am2901.GUIAm2901;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
public class SubmodelComponentTestbench
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIand;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIdlatch4;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUImux1_4;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIor4;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIram4;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIsel3_4;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIand;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUInand3;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIxor;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIsel2_4;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIsel3_4;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIand;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIfulladder;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUImux1;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIxor;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIand;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIdff;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUINandGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUINandGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIAndGate;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.GUINotGate;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
-import net.mograsim.logic.ui.model.components.TextComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUIAndGate;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.atomic.GUINotGate;
+import net.mograsim.logic.ui.model.components.atomic.TextComponent;
import net.mograsim.logic.ui.model.components.mi.nandbased.GUIdff;
import net.mograsim.logic.ui.model.components.mi.nandbased.am2901.GUIAm2901;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
import net.mograsim.logic.ui.model.wires.ConnectionPoint;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.ui.util.ModellingTool;
import net.mograsim.logic.core.types.BitVector.BitVectorMutator;
import net.mograsim.logic.ui.model.ViewModel;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.SubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
import net.mograsim.logic.ui.model.components.mi.nandbased.am2901.GUIAm2901;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.modeladapter.LogicModelParameters;
import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
net.mograsim.logic.ui.examples,
net.mograsim.logic.ui.model,
net.mograsim.logic.ui.model.components,
+ net.mograsim.logic.ui.model.components.atomic,
+ net.mograsim.logic.ui.model.components.submodels,
net.mograsim.logic.ui.model.wires,
net.mograsim.logic.ui.modeladapter,
net.mograsim.logic.ui.modeladapter.componentadapters,
+ net.mograsim.logic.ui.serializing,
net.mograsim.logic.ui.util
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.swt;bundle-version="3.0.0";visibility:=reexport,
--- /dev/null
+mograsim version: 0.1.2
+{
+ "GUIAm2901": "file:components/am2901/GUIAm2901.json",
+ "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
+ "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
+ "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
+ "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
+ "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
+ "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
+ "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
+ "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
+ "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
+ "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
+ "GUI_rsLatch": "file:components/GUI_rsLatch.json",
+ "GUIand": "file:components/GUIand.json",
+ "GUIand41": "file:components/GUIand41.json",
+ "GUIandor414": "file:components/GUIandor414.json",
+ "GUIdemux2": "file:components/GUIdemux2.json",
+ "GUIdff": "file:components/GUIdff.json",
+ "GUIdlatch": "file:components/GUIdlatch.json",
+ "GUIdlatch4": "file:components/GUIdlatch4.json",
+ "GUIfulladder": "file:components/GUIfulladder.json",
+ "GUIhalfadder": "file:components/GUIhalfadder.json",
+ "GUImux1": "file:components/GUImux1.json",
+ "GUImux1_4": "file:components/GUImux1_4.json",
+ "GUInand3": "file:components/GUInand3.json",
+ "GUInot4": "file:components/GUInot4.json",
+ "GUIor4": "file:components/GUIor4.json",
+ "GUIor_4": "file:components/GUIor_4.json",
+ "GUIram2": "file:components/GUIram2.json",
+ "GUIram4": "file:components/GUIram4.json",
+ "GUIsel2_4": "file:components/GUIsel2_4.json",
+ "GUIsel3_4": "file:components/GUIsel3_4.json",
+ "GUIxor": "file:components/GUIxor.json",
+ "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
+}
\ No newline at end of file
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.ui.model.ViewModel;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.SubmodelComponent;
-import net.mograsim.logic.ui.model.components.SubmodelInterface;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelInterface;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.preferences.Preferences;
import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
public class ClickableSubmodelComponentsTest
{
import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
import net.mograsim.logic.ui.SimpleLogicUIStandalone;
import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
-import net.mograsim.logic.ui.model.components.GUINotGate;
-import net.mograsim.logic.ui.model.components.GUIOrGate;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.atomic.GUINotGate;
+import net.mograsim.logic.ui.model.components.atomic.GUIOrGate;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import net.mograsim.logic.core.components.gates.AndGate;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
-
-public class GUIAndGate extends SimpleRectangularGUIGate
-{
- public GUIAndGate(ViewModelModifiable model, int logicWidth)
- {
- super(model, logicWidth, "&", false);
- setInputCount(2);// TODO make variable
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIAndGate.class, AndGate::new));
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import org.eclipse.swt.graphics.Color;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.components.BitDisplay;
-import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.BitDisplayAdapter;
-import net.mograsim.preferences.Preferences;
-
-public class GUIBitDisplay extends GUIComponent
-{
- private static final double width = 20;
- private static final double height = 15;
- private static final double fontHeight = 5;
-
- private final Pin inputPin;
-
- private final LogicObserver logicObs;
- private BitDisplay bitDisplay;
-
- public GUIBitDisplay(ViewModelModifiable model)
- {
- super(model);
- logicObs = (i) -> requestRedraw();
-
- setSize(width, height);
- addPin(this.inputPin = new Pin(this, "", 1, 0, height / 2));
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
- if (foreground != null)
- gc.setForeground(foreground);
- gc.drawRectangle(getBounds());
- String label = bitDisplay == null ? BitVectorFormatter.formatAsString(null)
- : BitVectorFormatter.formatAsString(bitDisplay.getDisplayedValue());
- Font oldFont = gc.getFont();
- Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
- gc.setFont(labelFont);
- Point textExtent = gc.textExtent(label);
- Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
- gc.setFont(oldFont);
- }
-
- public void setLogicModelBinding(BitDisplay bitDisplay)
- {
- if (this.bitDisplay != null)
- this.bitDisplay.deregisterObserver(logicObs);
- this.bitDisplay = bitDisplay;
- if (bitDisplay != null)
- bitDisplay.registerObserver(logicObs);
- }
-
- public boolean hasLogicModelBinding()
- {
- return bitDisplay != null;
- }
-
- public BitDisplay getBitDisplay()
- {
- return bitDisplay;
- }
-
- public Pin getInputPin()
- {
- return inputPin;
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new BitDisplayAdapter());
- }
-}
\ No newline at end of file
import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
/**
* The base class for all GUI components.<br>
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.wires.WireCrossPoint;
-import net.mograsim.logic.ui.util.JsonHandler;
-
-public class GUIComponentCreator
-{
- private final static Map<String, String> componentMapping;
-
- static
- {
- Map<String, String> tmp;
- try (InputStream s = GUIComponentCreator.class.getResourceAsStream("./mapping.json"))
- {
- tmp = JsonHandler.readJson(s, Map.class);
- }
- catch (IOException e)
- {
- System.err.println("Failed to initialize component mapping; Components cannot be created from file.");
- e.printStackTrace();
- tmp = new HashMap<>();
- }
- componentMapping = tmp;
- }
-
- public static GUIComponent create(ViewModelModifiable model, String name, Map<String, Object> params)
- {
- try
- {
- String path = componentMapping.get(name);
- if (path.startsWith("class:"))
- {
- path = path.substring(6);
- return createComponentFromClass(model, path, params);
- } else if (path.startsWith("file:"))
- {
- path = path.substring(5);
- return GUICustomComponentCreator.create(model, path);
- } else
- throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
- }
- catch (NullPointerException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
- | SecurityException | ClassNotFoundException | IllegalArgumentException e)
- {
- System.err.println("Failed to create requested component!");
- e.printStackTrace();
- return new SimpleRectangularSubmodelComponent(model, 1, "ERROR");
- }
- }
-
- private static GUIComponent createComponentFromClass(ViewModelModifiable model, String classname, Map<String, Object> params)
- throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
- ClassNotFoundException
- {
- Class<?> c = Class.forName(classname);
- Object comp;
- if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
- {
- Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
- comp = constructor.newInstance(model, ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
- } else
- {
- Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
- comp = constructor.newInstance(model);
- }
- return (GUIComponent) comp;
- }
-}
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerWireParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InterfacePinParams;
-import net.mograsim.logic.ui.model.wires.GUIWire;
-import net.mograsim.logic.ui.model.wires.MovablePin;
-
-/**
- * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
- */
-public final class GUICustomComponentCreator
-{
- private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
-
- /**
- * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
- * SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
- * {@link SubmodelComponentParams} describe.
- *
- * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent}
- * @return A new SubmodelComponent, as described in the file located at the given path
- */
- public static SubmodelComponent create(ViewModelModifiable model, String path)
- {
- try
- {
- SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
- SubmodelComponent ret = create(model, params);
- return ret;
- }
- catch (IOException e)
- {
- System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
- e.printStackTrace();
- }
- return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
- }
-
- /**
- * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent can also be
- * e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the {@link SubmodelComponentParams} describe.
- *
- * @param params The parameters describing the {@link SubmodelComponent}
- *
- * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
- */
- public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params)
- {
- SubmodelComponent comp = null;
- if (rectC.equals(params.type))
- {
- comp = createRectComponent(model, params);
- }
-
- if (comp == null)
- {
- comp = createSubmodelComponent(model, params);
- }
- comp.identifierDelegate = () -> params.name;
- initInnerComponents(comp, params.composition);
- return comp;
- }
-
- // May return null
- @SuppressWarnings("unchecked")
- private static SimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model, SubmodelComponentParams params)
- {
- try
- {
- Map<String, Object> m = params.specialized;
- SimpleRectangularSubmodelComponent rect = new SimpleRectangularSubmodelComponent(model,
- ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
- (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
- rect.setSubmodelScale(params.composition.innerScale);
-
- Object[] names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kInCount)).toArray();
- rect.setInputPins(Arrays.copyOf(names, names.length, String[].class));
-
- names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kOutCount)).toArray();
- rect.setOutputPins(Arrays.copyOf(names, names.length, String[].class));
-
- return rect;
- }
- catch (ClassCastException | NullPointerException e)
- {
- System.err.println("Failed to specialize component!");
- e.printStackTrace();
- return null;
- }
- }
-
- private static SubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
- {
- // As SubmodelComponent is abstract, for now SubmodelComponents are instantiated as SimpleRectangularSubmodelComponents
- SubmodelComponent comp = new SimpleRectangularSubmodelComponent(model, 0, "");
- comp.setSubmodelScale(params.composition.innerScale);
- comp.setSize(params.width, params.height);
- for (InterfacePinParams iPinParams : params.interfacePins)
- {
- comp.addSubmodelInterface(
- new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y));
- }
- return comp;
- }
-
- @SuppressWarnings("unused")
- private static void initInnerComponents(SubmodelComponent comp, ComponentCompositionParams params)
- {
- GUIComponent[] components = new GUIComponent[params.subComps.length];
- for (int i = 0; i < components.length; i++)
- {
- InnerComponentParams cParams = params.subComps[i];
- String path = cParams.name;
- components[i] = GUIComponentCreator.create(comp.submodelModifiable, cParams.name, cParams.params);
- components[i].moveTo(cParams.pos.x, cParams.pos.y);
- }
-
- for (int i = 0; i < params.innerWires.length; i++)
- {
- InnerWireParams innerWire = params.innerWires[i];
- new GUIWire(comp.submodelModifiable,
- comp.submodelModifiable.getComponents().get(innerWire.pin1.compId).getPin(innerWire.pin1.pinName),
- comp.submodelModifiable.getComponents().get(innerWire.pin2.compId).getPin(innerWire.pin2.pinName), innerWire.path);
- }
- }
-}
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import org.eclipse.swt.graphics.Color;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.core.LogicObservable;
-import net.mograsim.logic.core.LogicObserver;
-import net.mograsim.logic.core.components.ManualSwitch;
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVectorFormatter;
-import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.ManualSwitchAdapter;
-import net.mograsim.preferences.Preferences;
-
-public class GUIManualSwitch extends GUIComponent
-{
- private static final double width = 20;
- private static final double height = 15;
- private static final double fontHeight = 5;
-
- private final Pin outputPin;
-
- private final LogicObserver logicObs;
- private ManualSwitch logicSwitch;
- private ReadEnd end;
-
- public GUIManualSwitch(ViewModelModifiable model)
- {
- super(model);
- logicObs = (i) -> requestRedraw();
-
- setSize(width, height);
- addPin(this.outputPin = new Pin(this, "", 1, width, height / 2));
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- // TODO maybe draw switch state too?
- Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
- if (foreground != null)
- gc.setForeground(foreground);
- gc.drawRectangle(getBounds());
- String label = BitVectorFormatter.formatValueAsString(end);
- Font oldFont = gc.getFont();
- Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
- gc.setFont(labelFont);
- Point textExtent = gc.textExtent(label);
- Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
- gc.setFont(oldFont);
- }
-
- public void setLogicModelBinding(ManualSwitch logicSwitch, ReadEnd end)
- {
- deregisterLogicObs(this.end);
- deregisterLogicObs(this.logicSwitch);
- this.logicSwitch = logicSwitch;
- this.end = end;
- registerLogicObs(end);
- registerLogicObs(logicSwitch);
- }
-
- public boolean hasLogicModelBinding()
- {
- return logicSwitch != null;
- }
-
- @Override
- public void setHighLevelState(String stateID, Object newState)
- {
- switch (stateID)
- {
- case "out":
- if (logicSwitch != null)
- logicSwitch.setToValueOf((Bit) newState);
- break;
- default:
- super.setHighLevelState(stateID, newState);
- break;
- }
- }
-
- @Override
- public Object getHighLevelState(String stateID)
- {
- switch (stateID)
- {
- case "out":
- if (logicSwitch != null)
- return logicSwitch.getValue();
- return null;
- default:
- return super.getHighLevelState(stateID);
- }
- }
-
- private void registerLogicObs(LogicObservable observable)
- {
- if (observable != null)
- observable.registerObserver(logicObs);
- }
-
- private void deregisterLogicObs(LogicObservable observable)
- {
- if (observable != null)
- observable.deregisterObserver(logicObs);
- }
-
- @Override
- public boolean clicked(double x, double y)
- {
- if (logicSwitch != null)
- logicSwitch.toggle();
- return true;
- }
-
- public ManualSwitch getManualSwitch()
- {
- return logicSwitch;
- }
-
- public Pin getOutputPin()
- {
- return outputPin;
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new ManualSwitchAdapter());
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import net.mograsim.logic.core.components.gates.NandGate;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
-
-public class GUINandGate extends SimpleRectangularGUIGate
-{
- public GUINandGate(ViewModelModifiable model, int logicWidth)
- {
- super(model, logicWidth, "&", true);
- setInputCount(2);// TODO make variable
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINandGate.class, NandGate::new));
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import net.mograsim.logic.core.components.gates.NotGate;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
-
-public class GUINotGate extends SimpleRectangularGUIGate
-{
- public GUINotGate(ViewModelModifiable model, int logicWidth)
- {
- super(model, logicWidth, "1", true);
- setInputCount(1);
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new NotGate(t, p, i[0], o)));
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import net.mograsim.logic.core.components.gates.OrGate;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
-
-public class GUIOrGate extends SimpleRectangularGUIGate
-{
- public GUIOrGate(ViewModelModifiable model, int logicWidth)
- {
- super(model, logicWidth, "\u22651", false);// ">=1"
- setInputCount(2);
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIOrGate.class, OrGate::new));
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.swt.graphics.Color;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.wires.MovablePin;
-import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.preferences.Preferences;
-
-public class SimpleRectangularGUIGate extends GUIComponent
-{
- private static final double width = 20;
- private static final double pinDistance = 10;
- private static final double fontHeight = 5;
- private static final double invertedCircleDiam = 3.5;
-
- private final String label;
- protected final int logicWidth;
- private final boolean isInverted;
- private final double rectWidth;
-
- private MovablePin outputPin;
- private final List<Pin> inputPins;
-
- public static final String kLogicWidth = "logicWidth";
-
- protected SimpleRectangularGUIGate(ViewModelModifiable model, int logicWidth, String label, boolean isInverted)
- {
- super(model);
- this.label = label;
- this.logicWidth = logicWidth;
- this.isInverted = isInverted;
- this.rectWidth = width - (isInverted ? invertedCircleDiam : 0);
- this.outputPin = new MovablePin(this, "Y", logicWidth, width, 0);
- addPin(outputPin);
- this.inputPins = new ArrayList<>();
- setInputCount(1);
- }
-
- protected void setInputCount(int inputCount)
- {
- int oldInputCount = inputPins.size();
- setSize(width, inputCount * pinDistance);
- if (oldInputCount > inputCount)
- while (inputPins.size() > inputCount)
- removePin(inputPins.remove(inputCount).name);
- else if (oldInputCount < inputCount)
- for (int i = oldInputCount; i < inputCount; i++)
- {
- // TODO what for more than 24 input pins?
- Pin pin = new Pin(this, String.valueOf((char) ('A' + i)), logicWidth, 0, pinDistance / 2 + i * pinDistance);
- inputPins.add(pin);
- addPin(pin);
- }
- outputPin.setRelPos(width, inputCount * pinDistance / 2);
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
- if (foreground != null)
- gc.setForeground(foreground);
- double height = (getPins().size() - 1) * pinDistance;
- gc.drawRectangle(getPosX(), getPosY(), rectWidth, height);
- if (isInverted)
- gc.drawOval(getPosX() + rectWidth, getPosY() + (height - invertedCircleDiam) / 2, invertedCircleDiam, invertedCircleDiam);
- Font oldFont = gc.getFont();
- Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
- gc.setFont(labelFont);
- Point textExtent = gc.textExtent(label);
- Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(label, getPosX() + (rectWidth - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
- gc.setFont(oldFont);
- }
-
- @Override
- public Map<String, Object> getInstantiationParameters()
- {
- Map<String, Object> m = super.getInstantiationParameters();
- m.put(kLogicWidth, logicWidth);
- return m;
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.eclipse.swt.graphics.Color;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.wires.MovablePin;
-import net.mograsim.logic.ui.model.wires.Pin;
-import net.mograsim.preferences.Preferences;
-
-public class SimpleRectangularSubmodelComponent extends SubmodelComponent
-{
- public static String kLabel = "label", kInCount = "input_count", kOutCount = "output_count", kLogicWidth = "logic_width";
-
- private static final double width = 35;
- private static final double pinDistance = 10;
- private static final double pinNameMargin = .5;
- private static final double labelFontHeight = 5;
- private static final double pinNameFontHeight = 3.5;
-
- private final String label;
- protected final int logicWidth;
-
- private final List<String> inputPinNames;
- private final List<String> inputPinNamesUnmodifiable;
- private final List<String> outputPinNames;
- private final List<String> outputPinNamesUnmodifiable;
-
- protected SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
- {
- super(model);
- this.label = label;
- this.logicWidth = logicWidth;
- this.inputPinNames = new ArrayList<>();
- this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
- this.outputPinNames = new ArrayList<>();
- this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
- }
-
- protected void setInputPins(String... pinNames)
- {
- setIOPins(0, inputPinNames, outputPinNames, pinNames);
- }
-
- protected void setOutputPins(String... pinNames)
- {
- setIOPins(width, outputPinNames, inputPinNames, pinNames);
- }
-
- private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
- {
- int inputCount = newPinNames.length;
- List<String> newPinNamesList = Arrays.asList(newPinNames);
- if (new HashSet<>(newPinNamesList).size() != inputCount)
- throw new IllegalArgumentException("Pin names contain duplicates");
- for (String pinName : newPinNamesList)
- if (pinNamesListOtherSide.contains(pinName))
- throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
- super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
- for (int i = 0; i < inputCount; i++)
- {
- String pinName = newPinNames[i];
- int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
- if (oldPinIndex == -1)
- super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
- else
- getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
- }
- for (String pinName : pinNamesListThisSide)
- if (!newPinNamesList.contains(pinName))
- super.removeSubmodelInterface(pinName);
- pinNamesListThisSide.clear();
- pinNamesListThisSide.addAll(newPinNamesList);
- }
-
- public List<String> getInputPinNames()
- {
- return inputPinNamesUnmodifiable;
- }
-
- public List<String> getOutputPinNames()
- {
- return outputPinNamesUnmodifiable;
- }
-
- @Override
- protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
- {
- Font oldFont = gc.getFont();
- gc.setFont(new Font(oldFont.getName(), labelFontHeight, oldFont.getStyle()));
- Point textExtent = gc.textExtent(label);
- Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(label, getPosX() + (getWidth() - textExtent.x) / 2, getPosY() + (getHeight() - textExtent.y) / 2, true);
- gc.setFont(new Font(oldFont.getName(), pinNameFontHeight, oldFont.getStyle()));
- for (int i = 0; i < inputPinNames.size(); i++)
- {
- String pinName = inputPinNames.get(i);
- textExtent = gc.textExtent(pinName);
- gc.drawText(pinName, getPosX() + pinNameMargin, getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
- }
- for (int i = 0; i < outputPinNames.size(); i++)
- {
- String pinName = outputPinNames.get(i);
- textExtent = gc.textExtent(pinName);
- gc.drawText(pinName, getPosX() + width - textExtent.x - pinNameMargin,
- getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
- }
- gc.setFont(oldFont);
- }
-
- @Override
- protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
- {
- Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
- if (foreground != null)
- gc.setForeground(foreground);
- gc.drawRectangle(getBounds());
- }
-
- @Override
- public SubmodelComponentParams calculateParams()
- {
- SubmodelComponentParams ret = super.calculateParams();
- ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName();
- Map<String, Object> m = new TreeMap<>();
- m.put(kLabel, label);
- m.put(kInCount, inputPinNames.toArray());
- m.put(kOutCount, outputPinNames.toArray());
- m.put(kLogicWidth, logicWidth);
- ret.specialized = m;
- return ret;
- }
-
- @Override
- protected Pin addSubmodelInterface(MovablePin supermodelPin)
- {
- throw new UnsupportedOperationException(
- "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
- }
-
- @Override
- protected void removeSubmodelInterface(String name)
- {
- throw new UnsupportedOperationException(
- "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
- }
-
- @Override
- protected void setSize(double width, double height)
- {
- throw new UnsupportedOperationException(
- "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
- }
-}
\ No newline at end of file
+++ /dev/null
-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;
-import net.haspamelodica.swt.helper.gcs.TranslatedGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.ui.LogicUIRenderer;
-import net.mograsim.logic.ui.model.ViewModel;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerPinParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InnerWireParams;
-import net.mograsim.logic.ui.model.components.SubmodelComponentParams.InterfacePinParams;
-import net.mograsim.logic.ui.model.wires.GUIWire;
-import net.mograsim.logic.ui.model.wires.MovablePin;
-import net.mograsim.logic.ui.model.wires.Pin;
-
-/**
- * A {@link GUIComponent} consisting of another model. A <code>SubmodelComponent</code> can have so-called "interface pins" connecting the
- * inner and outer models.
- */
-public abstract class SubmodelComponent extends GUIComponent
-{
- /**
- * A modifiable view of {@link #submodel}.
- */
- protected final ViewModelModifiable submodelModifiable;
- /**
- * The model this {@link SubmodelComponent} consists of.
- */
- public final ViewModel submodel;
- /**
- * The list of all submodel interface pins of this {@link SubmodelComponent} on the submodel side.
- */
- private final Map<String, MovablePin> submodelPins;
- /**
- * An unmodifiable view of {@link #submodelPins}.
- */
- private final Map<String, MovablePin> submodelMovablePinsUnmodifiable;
- /**
- * An unmodifiable view of {@link #submodelPins} where pins are not movable.
- */
- private final Map<String, Pin> submodelUnmovablePinsUnmodifiable;
- /**
- * The list of all submodel interface pins of this {@link SubmodelComponent} on the supermodel side.
- */
- private final Map<String, MovablePin> supermodelPins;
- /**
- * An unmodifiable view of {@link #supermodelPins}.
- */
- private final Map<String, MovablePin> supermodelMovablePinsUnmodifiable;
- /**
- * An unmodifiable view of {@link #supermodelPins} where pins are not movable.
- */
- private final Map<String, Pin> supermodelUnmovablePinsUnmodifiable;
- /**
- * A pseudo-component containing all submodel interface pins on the submodel side.
- */
- 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.
- */
- private double submodelScale;
- /**
- * If this {@link SubmodelComponent} fills at least this amount of the visible region vertically or horizontally, the submodel starts to
- * be visible.
- */
- private double maxVisibleRegionFillRatioForAlpha0;
- /**
- * If this {@link SubmodelComponent} fills at least this amount of the visible region vertically or horizontally, the submodel is fully
- * visible.
- */
- private double minVisibleRegionFillRatioForAlpha1;
- /**
- * The renderer used for rendering the submodel.
- */
- private final LogicUIRenderer renderer;
-
- // creation and destruction
-
- public SubmodelComponent(ViewModelModifiable model)
- {
- super(model);
- this.submodelModifiable = new ViewModelModifiable();
- this.submodel = submodelModifiable;
- this.submodelPins = new HashMap<>();
- this.submodelMovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins);
- this.submodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins);
- this.supermodelPins = new HashMap<>();
- this.supermodelMovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins);
- 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;
- this.renderer = new LogicUIRenderer(submodelModifiable);
-
- submodelModifiable.addRedrawListener(this::requestRedraw);
- }
-
- // pins
-
- /**
- * Adds a new submodel interface pin.
- *
- * @param supermodelPin the submodel interface pin on the supermodel side
- *
- * @return the submodel interface pin on the submodel side
- *
- * @author Daniel Kirschten
- */
- protected Pin addSubmodelInterface(MovablePin supermodelPin)
- {
- super.addPin(supermodelPin);// do this first to be fail-fast if the supermodel does not belong to this component
-
- String name = supermodelPin.name;
- MovablePin submodelPin = new MovablePin(submodelInterface, name, supermodelPin.logicWidth, supermodelPin.getRelX() / submodelScale,
- supermodelPin.getRelY() / submodelScale);
-
- submodelPin.addPinMovedListener(p ->
- {
- double newRelX = p.getRelX() * submodelScale;
- double newRelY = p.getRelY() * submodelScale;
- if (supermodelPin.getRelX() != newRelX || supermodelPin.getRelY() != newRelY)
- supermodelPin.setRelPos(newRelX, newRelY);
- });
- supermodelPin.addPinMovedListener(p ->
- {
- double newRelX = p.getRelX() / submodelScale;
- double newRelY = p.getRelY() / submodelScale;
- if (submodelPin.getRelX() != newRelX || submodelPin.getRelY() != newRelY)
- submodelPin.setRelPos(newRelX, newRelY);
- });
-
- submodelInterface.addPin(submodelPin);
-
- submodelPins.put(name, submodelPin);
- supermodelPins.put(name, supermodelPin);
-
- // no need to call requestRedraw() because addPin() will request a redraw
- return submodelPin;
- }
-
- /**
- * Removes a submodel interface pin.
- *
- * @author Daniel Kirschten
- */
- protected void removeSubmodelInterface(String name)
- {
- super.removePin(name);// do this first to be fail-fast if this component doesn't have a pin with the given name
- Pin submodelPin = submodelPins.remove(name);
- submodelInterface.removePin(submodelPin.name);
- supermodelPins.remove(name);
-
- // no need to call requestRedraw() because removePin() will request a redraw
- }
-
- /**
- * Returns a collection of submodel interface pins on the submodel side of this component.
- *
- * @author Daniel Kirschten
- */
- public Map<String, Pin> getSubmodelPins()
- {
- return submodelUnmovablePinsUnmodifiable;
- }
-
- /**
- * Returns the submodel interface pin with the given name on the submodel side of this component.
- *
- * @author Daniel Kirschten
- */
- public Pin getSubmodelPin(String name)
- {
- return getSubmodelMovablePin(name);
- }
-
- /**
- * Returns a collection of movable submodel interface pins on the submodel side of this component.
- *
- * @author Daniel Kirschten
- */
- protected Map<String, MovablePin> getSubmodelMovablePins()
- {
- return submodelMovablePinsUnmodifiable;
- }
-
- /**
- * Returns the movable submodel interface pin with the given name on the submodel side of this component.
- *
- * @author Daniel Kirschten
- */
- protected MovablePin getSubmodelMovablePin(String name)
- {
- return submodelPins.get(name);
- }
-
- /**
- * Returns a collection of submodel interface pins on the supermodel side of this component.
- *
- * @author Daniel Kirschten
- */
- public Map<String, Pin> getSupermodelPins()
- {
- return supermodelUnmovablePinsUnmodifiable;
- }
-
- /**
- * Returns the submodel interface pin with the given name on the supermodel side of this component.
- *
- * @author Daniel Kirschten
- */
- public Pin getSupermodelPin(String name)
- {
- return getSupermodelMovablePin(name);
- }
-
- /**
- * Returns a collection of movable submodel interface pins on the supermodel side of this component.
- *
- * @author Daniel Kirschten
- */
- protected Map<String, MovablePin> getSupermodelMovablePins()
- {
- return supermodelMovablePinsUnmodifiable;
- }
-
- /**
- * Returns the movable submodel interface pin with the given name on the supermodel side of this component.
- *
- * @author Daniel Kirschten
- */
- protected MovablePin getSupermodelMovablePin(String name)
- {
- 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
-
- /**
- * Sets the factor by which the submodel is scaled when rendering and calls redrawListeners. Note that the submodel interface pins will
- * stay at their position relative to the supermodel, which means they will move relative to the submodel.
- *
- * @author Daniel Kirschten
- */
- protected void setSubmodelScale(double submodelScale)
- {
- this.submodelScale = submodelScale;
-
- for (Entry<String, MovablePin> e : supermodelPins.entrySet())
- getSubmodelMovablePin(e.getKey()).setRelPos(e.getValue().getRelX() * submodelScale, e.getValue().getRelY() * submodelScale);
-
- requestRedraw();// needed if there is no submodel interface pin
- }
-
- /**
- * Returns the current factor by which the submodel is scaled when rendering.
- *
- * @author Daniel Kirschten
- */
- protected double getSubmodelScale()
- {
- return submodelScale;
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- GCConfig conf = new GCConfig(gc);
- TranslatedGC tgc = new TranslatedGC(gc, getPosX(), getPosY(), submodelScale, true);
- conf.reset(tgc);
- double visibleRegionFillRatio = Math.max(getWidth() / visibleRegion.width, getHeight() / visibleRegion.height);
- double alphaFactor = map(visibleRegionFillRatio, maxVisibleRegionFillRatioForAlpha0, minVisibleRegionFillRatioForAlpha1, 0, 1);
- alphaFactor = Math.max(0, Math.min(1, alphaFactor));
- // we need to take the old alpha into account to support nested submodules better.
- int oldAlpha = gc.getAlpha();
- int submodelAlpha = Math.max(0, Math.min(255, (int) (oldAlpha * alphaFactor)));
- int labelAlpha = Math.max(0, Math.min(255, (int) (oldAlpha * (1 - alphaFactor))));
- if (submodelAlpha != 0)
- {
- gc.setAlpha(submodelAlpha);
- renderer.render(tgc, visibleRegion.translate(getPosX() / submodelScale, getPosY() / submodelScale, 1 / submodelScale));
- }
- if (labelAlpha != 0)
- {
- gc.setAlpha(labelAlpha);
- renderSymbol(gc, visibleRegion);
- }
- conf.reset(gc);
- // draw the outline after all other operations to make interface pins look better
- 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 mapMin + (val - valMin) * (mapMax - mapMin) / (valMax - valMin);
- }
-
- @Override
- public boolean clicked(double x, double y)
- {
- double scaledX = (x - getPosX()) / submodelScale;
- double scaledY = (y - getPosY()) / submodelScale;
- for (GUIComponent component : submodel.getComponents())
- if (component.getBounds().contains(scaledX, scaledY) && component.clicked(scaledX, scaledY))
- return true;
- return false;
- }
-
- // serializing
-
- /**
- * @return {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}.
- */
- public SubmodelComponentParams calculateParams()
- {
- SubmodelComponentParams params = new SubmodelComponentParams();
- params.name = getIdentifier();
- params.type = SubmodelComponent.class.getSimpleName();
- params.composition = calculateCompositionParams();
-
- params.width = getWidth();
- params.height = getHeight();
-
- InterfacePinParams[] iPins = new InterfacePinParams[getPins().size()];
- int i = 0;
- for (Pin p : getPins().values())
- {
- InterfacePinParams iPinParams = new InterfacePinParams();
- iPins[i] = iPinParams;
- iPinParams.location = p.getRelPos();
- iPinParams.name = p.name;
- iPinParams.logicWidth = p.logicWidth;
- i++;
- }
- params.interfacePins = iPins;
- return params;
- }
-
- protected ComponentCompositionParams calculateCompositionParams()
- {
- ComponentCompositionParams params = new ComponentCompositionParams();
- params.innerScale = getSubmodelScale();
-
- List<GUIComponent> compList = submodelModifiable.getComponents();
- Iterator<GUIComponent> componentIt = compList.iterator();
- componentIt.next(); // Skip inner SubmodelInterface
- InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1];
- int i = 0;
- while (componentIt.hasNext())
- {
- GUIComponent component = componentIt.next();
- InnerComponentParams inner = new InnerComponentParams();
- comps[i] = inner;
- inner.params = component.getInstantiationParameters();
- inner.pos = new Point(component.getPosX(), component.getPosY());
- inner.name = component.getIdentifier();
- i++;
- }
- params.subComps = comps;
-
- List<GUIWire> wireList = submodelModifiable.getWires();
- InnerWireParams wires[] = new InnerWireParams[wireList.size()];
- i = 0;
- for (GUIWire wire : wireList)
- {
- InnerWireParams inner = new InnerWireParams();
- wires[i] = inner;
- InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams();
-
- pin1Params.pinName = wire.getPin1().name;
- pin1Params.compId = compList.indexOf(wire.getPin1().component);
- pin2Params.pinName = wire.getPin2().name;
- pin2Params.compId = compList.indexOf(wire.getPin2().component);
- inner.pin1 = pin1Params;
- inner.pin2 = pin2Params;
- inner.path = wire.getPath();
- i++;
- }
- params.innerWires = wires;
- return params;
- }
-
- // operations no longer supported
-
- @Override
- protected void addPin(Pin pin)
- {
- throw new UnsupportedOperationException("Can't add pins to a SubmodelComponent directly, call addSubmodelInterface instead");
- }
-
- @Override
- protected void removePin(String name)
- {
- throw new UnsupportedOperationException("Can't remove pins of a SubmodelComponent directly, call removeSubmodelInterface instead");
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import java.io.IOException;
-import java.util.Map;
-
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.mograsim.logic.ui.util.JsonHandler;
-
-/**
- * This class contains all the information necessary to create a new {@link SubmodelComponent}
- */
-public class SubmodelComponentParams
-{
- String type, name;
- double width, height;
- InterfacePinParams[] interfacePins;
- ComponentCompositionParams composition;
- Map<String, Object> specialized;
-
- public static class InterfacePinParams
- {
- Point location;
- String name;
- int logicWidth;
- }
-
- public static class InnerWireParams
- {
- InnerPinParams pin1, pin2;
- Point[] path;
- }
-
- public static class InnerPinParams
- {
- int compId;
- String pinName;
- }
-
- public static class ComponentCompositionParams
- {
- double innerScale;
- InnerComponentParams[] subComps;
- InnerWireParams[] innerWires;
-
- public static class InnerComponentParams
- {
- Point pos;
- String name;
- Map<String, Object> params;
- }
- }
-
- public static SubmodelComponentParams readJson(String path) throws IOException
- {
- return JsonHandler.readJson(path, SubmodelComponentParams.class);
- }
-
- /**
- * Writes this {@link SubmodelComponentParams} object into a file in json format. The correct file extension is important! Check
- * {@link SubmodelComponentParams}.fileExtension
- */
- public void writeJson(String path)
- {
- try
- {
- JsonHandler.writeJson(this, path);
- }
- catch (IOException e)
- {
- System.err.println("Failed to write SubComponentParams to file");
- e.printStackTrace();
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-
-public class SubmodelInterface extends GUIComponent
-{
- public SubmodelInterface(ViewModelModifiable model)
- {
- super(model);
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {// nothing to do here
- }
-}
\ No newline at end of file
+++ /dev/null
-package net.mograsim.logic.ui.model.components;
-
-import org.eclipse.swt.graphics.Color;
-
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
-import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
-import net.mograsim.logic.ui.model.ViewModelModifiable;
-import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
-import net.mograsim.logic.ui.modeladapter.componentadapters.NoLogicAdapter;
-import net.mograsim.preferences.Preferences;
-
-//TODO clean size calculation mess
-public class TextComponent extends GUIComponent
-{
- private final String text;
-
- public TextComponent(ViewModelModifiable model, String text)
- {
- super(model);
- this.text = text;
- // If size is unset, it defaults to 0, which could prohibit this component from being rendered, which would prohibit the size being
- // set to a better guess
- setSize(1, 1);
- }
-
- @Override
- public void render(GeneralGC gc, Rectangle visibleRegion)
- {
- Point textExtent = gc.textExtent(text);
- setSize(textExtent.x, textExtent.y);
-
- Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
- if (textColor != null)
- gc.setForeground(textColor);
- gc.drawText(text, getPosX(), getPosY(), true);
- }
-
- static
- {
- ViewLogicModelAdapter.addComponentAdapter(new NoLogicAdapter<>(TextComponent.class));
- }
-}
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import net.mograsim.logic.core.components.gates.AndGate;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
+
+public class GUIAndGate extends SimpleRectangularGUIGate
+{
+ public GUIAndGate(ViewModelModifiable model, int logicWidth)
+ {
+ super(model, logicWidth, "&", false);
+ setInputCount(2);// TODO make variable
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIAndGate.class, AndGate::new));
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import org.eclipse.swt.graphics.Color;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.core.LogicObserver;
+import net.mograsim.logic.core.components.BitDisplay;
+import net.mograsim.logic.core.types.BitVectorFormatter;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.BitDisplayAdapter;
+import net.mograsim.preferences.Preferences;
+
+public class GUIBitDisplay extends GUIComponent
+{
+ private static final double width = 20;
+ private static final double height = 15;
+ private static final double fontHeight = 5;
+
+ private final Pin inputPin;
+
+ private final LogicObserver logicObs;
+ private BitDisplay bitDisplay;
+
+ public GUIBitDisplay(ViewModelModifiable model)
+ {
+ super(model);
+ logicObs = (i) -> requestRedraw();
+
+ setSize(width, height);
+ addPin(this.inputPin = new Pin(this, "", 1, 0, height / 2));
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
+ if (foreground != null)
+ gc.setForeground(foreground);
+ gc.drawRectangle(getBounds());
+ String label = bitDisplay == null ? BitVectorFormatter.formatAsString(null)
+ : BitVectorFormatter.formatAsString(bitDisplay.getDisplayedValue());
+ Font oldFont = gc.getFont();
+ Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
+ gc.setFont(labelFont);
+ Point textExtent = gc.textExtent(label);
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
+ gc.setFont(oldFont);
+ }
+
+ public void setLogicModelBinding(BitDisplay bitDisplay)
+ {
+ if (this.bitDisplay != null)
+ this.bitDisplay.deregisterObserver(logicObs);
+ this.bitDisplay = bitDisplay;
+ if (bitDisplay != null)
+ bitDisplay.registerObserver(logicObs);
+ }
+
+ public boolean hasLogicModelBinding()
+ {
+ return bitDisplay != null;
+ }
+
+ public BitDisplay getBitDisplay()
+ {
+ return bitDisplay;
+ }
+
+ public Pin getInputPin()
+ {
+ return inputPin;
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new BitDisplayAdapter());
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import org.eclipse.swt.graphics.Color;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.core.LogicObservable;
+import net.mograsim.logic.core.LogicObserver;
+import net.mograsim.logic.core.components.ManualSwitch;
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVectorFormatter;
+import net.mograsim.logic.core.wires.Wire.ReadEnd;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.ManualSwitchAdapter;
+import net.mograsim.preferences.Preferences;
+
+public class GUIManualSwitch extends GUIComponent
+{
+ private static final double width = 20;
+ private static final double height = 15;
+ private static final double fontHeight = 5;
+
+ private final Pin outputPin;
+
+ private final LogicObserver logicObs;
+ private ManualSwitch logicSwitch;
+ private ReadEnd end;
+
+ public GUIManualSwitch(ViewModelModifiable model)
+ {
+ super(model);
+ logicObs = (i) -> requestRedraw();
+
+ setSize(width, height);
+ addPin(this.outputPin = new Pin(this, "", 1, width, height / 2));
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ // TODO maybe draw switch state too?
+ Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
+ if (foreground != null)
+ gc.setForeground(foreground);
+ gc.drawRectangle(getBounds());
+ String label = BitVectorFormatter.formatValueAsString(end);
+ Font oldFont = gc.getFont();
+ Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
+ gc.setFont(labelFont);
+ Point textExtent = gc.textExtent(label);
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(label, getPosX() + (width - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
+ gc.setFont(oldFont);
+ }
+
+ public void setLogicModelBinding(ManualSwitch logicSwitch, ReadEnd end)
+ {
+ deregisterLogicObs(this.end);
+ deregisterLogicObs(this.logicSwitch);
+ this.logicSwitch = logicSwitch;
+ this.end = end;
+ registerLogicObs(end);
+ registerLogicObs(logicSwitch);
+ }
+
+ public boolean hasLogicModelBinding()
+ {
+ return logicSwitch != null;
+ }
+
+ @Override
+ public void setHighLevelState(String stateID, Object newState)
+ {
+ switch (stateID)
+ {
+ case "out":
+ if (logicSwitch != null)
+ logicSwitch.setToValueOf((Bit) newState);
+ break;
+ default:
+ super.setHighLevelState(stateID, newState);
+ break;
+ }
+ }
+
+ @Override
+ public Object getHighLevelState(String stateID)
+ {
+ switch (stateID)
+ {
+ case "out":
+ if (logicSwitch != null)
+ return logicSwitch.getValue();
+ return null;
+ default:
+ return super.getHighLevelState(stateID);
+ }
+ }
+
+ private void registerLogicObs(LogicObservable observable)
+ {
+ if (observable != null)
+ observable.registerObserver(logicObs);
+ }
+
+ private void deregisterLogicObs(LogicObservable observable)
+ {
+ if (observable != null)
+ observable.deregisterObserver(logicObs);
+ }
+
+ @Override
+ public boolean clicked(double x, double y)
+ {
+ if (logicSwitch != null)
+ logicSwitch.toggle();
+ return true;
+ }
+
+ public ManualSwitch getManualSwitch()
+ {
+ return logicSwitch;
+ }
+
+ public Pin getOutputPin()
+ {
+ return outputPin;
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new ManualSwitchAdapter());
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import net.mograsim.logic.core.components.gates.NandGate;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
+
+public class GUINandGate extends SimpleRectangularGUIGate
+{
+ public GUINandGate(ViewModelModifiable model, int logicWidth)
+ {
+ super(model, logicWidth, "&", true);
+ setInputCount(2);// TODO make variable
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINandGate.class, NandGate::new));
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import net.mograsim.logic.core.components.gates.NotGate;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
+
+public class GUINotGate extends SimpleRectangularGUIGate
+{
+ public GUINotGate(ViewModelModifiable model, int logicWidth)
+ {
+ super(model, logicWidth, "1", true);
+ setInputCount(1);
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new NotGate(t, p, i[0], o)));
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import net.mograsim.logic.core.components.gates.OrGate;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter;
+
+public class GUIOrGate extends SimpleRectangularGUIGate
+{
+ public GUIOrGate(ViewModelModifiable model, int logicWidth)
+ {
+ super(model, logicWidth, "\u22651", false);// ">=1"
+ setInputCount(2);
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new SimpleGateAdapter<>(GUIOrGate.class, OrGate::new));
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.MovablePin;
+import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.preferences.Preferences;
+
+public class SimpleRectangularGUIGate extends GUIComponent
+{
+ private static final double width = 20;
+ private static final double pinDistance = 10;
+ private static final double fontHeight = 5;
+ private static final double invertedCircleDiam = 3.5;
+
+ private final String label;
+ protected final int logicWidth;
+ private final boolean isInverted;
+ private final double rectWidth;
+
+ private MovablePin outputPin;
+ private final List<Pin> inputPins;
+
+ public static final String kLogicWidth = "logicWidth";
+
+ protected SimpleRectangularGUIGate(ViewModelModifiable model, int logicWidth, String label, boolean isInverted)
+ {
+ super(model);
+ this.label = label;
+ this.logicWidth = logicWidth;
+ this.isInverted = isInverted;
+ this.rectWidth = width - (isInverted ? invertedCircleDiam : 0);
+ this.outputPin = new MovablePin(this, "Y", logicWidth, width, 0);
+ addPin(outputPin);
+ this.inputPins = new ArrayList<>();
+ setInputCount(1);
+ }
+
+ protected void setInputCount(int inputCount)
+ {
+ int oldInputCount = inputPins.size();
+ setSize(width, inputCount * pinDistance);
+ if (oldInputCount > inputCount)
+ while (inputPins.size() > inputCount)
+ removePin(inputPins.remove(inputCount).name);
+ else if (oldInputCount < inputCount)
+ for (int i = oldInputCount; i < inputCount; i++)
+ {
+ // TODO what for more than 24 input pins?
+ Pin pin = new Pin(this, String.valueOf((char) ('A' + i)), logicWidth, 0, pinDistance / 2 + i * pinDistance);
+ inputPins.add(pin);
+ addPin(pin);
+ }
+ outputPin.setRelPos(width, inputCount * pinDistance / 2);
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
+ if (foreground != null)
+ gc.setForeground(foreground);
+ double height = (getPins().size() - 1) * pinDistance;
+ gc.drawRectangle(getPosX(), getPosY(), rectWidth, height);
+ if (isInverted)
+ gc.drawOval(getPosX() + rectWidth, getPosY() + (height - invertedCircleDiam) / 2, invertedCircleDiam, invertedCircleDiam);
+ Font oldFont = gc.getFont();
+ Font labelFont = new Font(oldFont.getName(), fontHeight, oldFont.getStyle());
+ gc.setFont(labelFont);
+ Point textExtent = gc.textExtent(label);
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(label, getPosX() + (rectWidth - textExtent.x) / 2, getPosY() + (height - textExtent.y) / 2, true);
+ gc.setFont(oldFont);
+ }
+
+ @Override
+ public Map<String, Object> getInstantiationParameters()
+ {
+ Map<String, Object> m = super.getInstantiationParameters();
+ m.put(kLogicWidth, logicWidth);
+ return m;
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.atomic;
+
+import org.eclipse.swt.graphics.Color;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.modeladapter.ViewLogicModelAdapter;
+import net.mograsim.logic.ui.modeladapter.componentadapters.NoLogicAdapter;
+import net.mograsim.preferences.Preferences;
+
+//TODO clean size calculation mess
+public class TextComponent extends GUIComponent
+{
+ private final String text;
+
+ public TextComponent(ViewModelModifiable model, String text)
+ {
+ super(model);
+ this.text = text;
+ // If size is unset, it defaults to 0, which could prohibit this component from being rendered, which would prohibit the size being
+ // set to a better guess
+ setSize(1, 1);
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ Point textExtent = gc.textExtent(text);
+ setSize(textExtent.x, textExtent.y);
+
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(text, getPosX(), getPosY(), true);
+ }
+
+ static
+ {
+ ViewLogicModelAdapter.addComponentAdapter(new NoLogicAdapter<>(TextComponent.class));
+ }
+}
+++ /dev/null
-mograsim version: 0.1.2
-{
- "GUIAm2901": "file:components/am2901/GUIAm2901.json",
- "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
- "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
- "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
- "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
- "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
- "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
- "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
- "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
- "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
- "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
- "GUI_rsLatch": "file:components/GUI_rsLatch.json",
- "GUIand": "file:components/GUIand.json",
- "GUIand41": "file:components/GUIand41.json",
- "GUIandor414": "file:components/GUIandor414.json",
- "GUIdemux2": "file:components/GUIdemux2.json",
- "GUIdff": "file:components/GUIdff.json",
- "GUIdlatch": "file:components/GUIdlatch.json",
- "GUIdlatch4": "file:components/GUIdlatch4.json",
- "GUIfulladder": "file:components/GUIfulladder.json",
- "GUIhalfadder": "file:components/GUIhalfadder.json",
- "GUImux1": "file:components/GUImux1.json",
- "GUImux1_4": "file:components/GUImux1_4.json",
- "GUInand3": "file:components/GUInand3.json",
- "GUInot4": "file:components/GUInot4.json",
- "GUIor4": "file:components/GUIor4.json",
- "GUIor_4": "file:components/GUIor_4.json",
- "GUIram2": "file:components/GUIram2.json",
- "GUIram4": "file:components/GUIram4.json",
- "GUIsel2_4": "file:components/GUIsel2_4.json",
- "GUIsel3_4": "file:components/GUIsel3_4.json",
- "GUIxor": "file:components/GUIxor.json",
- "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
-}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.submodels;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.eclipse.swt.graphics.Color;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.wires.MovablePin;
+import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
+import net.mograsim.preferences.Preferences;
+
+public class SimpleRectangularSubmodelComponent extends SubmodelComponent
+{
+ public static String kLabel = "label", kInCount = "input_count", kOutCount = "output_count", kLogicWidth = "logic_width";
+
+ private static final double width = 35;
+ private static final double pinDistance = 10;
+ private static final double pinNameMargin = .5;
+ private static final double labelFontHeight = 5;
+ private static final double pinNameFontHeight = 3.5;
+
+ private final String label;
+ protected final int logicWidth;
+
+ private final List<String> inputPinNames;
+ private final List<String> inputPinNamesUnmodifiable;
+ private final List<String> outputPinNames;
+ private final List<String> outputPinNamesUnmodifiable;
+
+ public SimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
+ {
+ super(model);
+ this.label = label;
+ this.logicWidth = logicWidth;
+ this.inputPinNames = new ArrayList<>();
+ this.inputPinNamesUnmodifiable = Collections.unmodifiableList(inputPinNames);
+ this.outputPinNames = new ArrayList<>();
+ this.outputPinNamesUnmodifiable = Collections.unmodifiableList(outputPinNames);
+ }
+
+ protected void setInputPins(String... pinNames)
+ {
+ setIOPins(0, inputPinNames, outputPinNames, pinNames);
+ }
+
+ protected void setOutputPins(String... pinNames)
+ {
+ setIOPins(width, outputPinNames, inputPinNames, pinNames);
+ }
+
+ private void setIOPins(double relX, List<String> pinNamesListThisSide, List<String> pinNamesListOtherSide, String... newPinNames)
+ {
+ int inputCount = newPinNames.length;
+ List<String> newPinNamesList = Arrays.asList(newPinNames);
+ if (new HashSet<>(newPinNamesList).size() != inputCount)
+ throw new IllegalArgumentException("Pin names contain duplicates");
+ for (String pinName : newPinNamesList)
+ if (pinNamesListOtherSide.contains(pinName))
+ throw new IllegalArgumentException("Can't add pin. There is a pin on the other side with the same name: " + pinName);
+ super.setSize(width, Math.max(inputCount, pinNamesListOtherSide.size()) * pinDistance);
+ for (int i = 0; i < inputCount; i++)
+ {
+ String pinName = newPinNames[i];
+ int oldPinIndex = pinNamesListThisSide.indexOf(pinName);
+ if (oldPinIndex == -1)
+ super.addSubmodelInterface(new MovablePin(this, pinName, logicWidth, relX, pinDistance / 2 + i * pinDistance));
+ else
+ getSupermodelMovablePin(pinName).setRelPos(relX, pinDistance / 2 + i * pinDistance);
+ }
+ for (String pinName : pinNamesListThisSide)
+ if (!newPinNamesList.contains(pinName))
+ super.removeSubmodelInterface(pinName);
+ pinNamesListThisSide.clear();
+ pinNamesListThisSide.addAll(newPinNamesList);
+ }
+
+ public List<String> getInputPinNames()
+ {
+ return inputPinNamesUnmodifiable;
+ }
+
+ public List<String> getOutputPinNames()
+ {
+ return outputPinNamesUnmodifiable;
+ }
+
+ @Override
+ protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
+ {
+ Font oldFont = gc.getFont();
+ gc.setFont(new Font(oldFont.getName(), labelFontHeight, oldFont.getStyle()));
+ Point textExtent = gc.textExtent(label);
+ Color textColor = Preferences.current().getColor("net.mograsim.logic.ui.color.text");
+ if (textColor != null)
+ gc.setForeground(textColor);
+ gc.drawText(label, getPosX() + (getWidth() - textExtent.x) / 2, getPosY() + (getHeight() - textExtent.y) / 2, true);
+ gc.setFont(new Font(oldFont.getName(), pinNameFontHeight, oldFont.getStyle()));
+ for (int i = 0; i < inputPinNames.size(); i++)
+ {
+ String pinName = inputPinNames.get(i);
+ textExtent = gc.textExtent(pinName);
+ gc.drawText(pinName, getPosX() + pinNameMargin, getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
+ }
+ for (int i = 0; i < outputPinNames.size(); i++)
+ {
+ String pinName = outputPinNames.get(i);
+ textExtent = gc.textExtent(pinName);
+ gc.drawText(pinName, getPosX() + width - textExtent.x - pinNameMargin,
+ getPosY() + i * pinDistance + (pinDistance - textExtent.y) / 2, true);
+ }
+ gc.setFont(oldFont);
+ }
+
+ @Override
+ protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
+ {
+ Color foreground = Preferences.current().getColor("net.mograsim.logic.ui.color.foreground");
+ if (foreground != null)
+ gc.setForeground(foreground);
+ gc.drawRectangle(getBounds());
+ }
+
+ @Override
+ public SubmodelComponentParams calculateParams()
+ {
+ SubmodelComponentParams ret = super.calculateParams();
+ ret.type = SimpleRectangularSubmodelComponent.class.getSimpleName();
+ Map<String, Object> m = new TreeMap<>();
+ m.put(kLabel, label);
+ m.put(kInCount, inputPinNames.toArray());
+ m.put(kOutCount, outputPinNames.toArray());
+ m.put(kLogicWidth, logicWidth);
+ ret.specialized = m;
+ return ret;
+ }
+
+ @Override
+ protected Pin addSubmodelInterface(MovablePin supermodelPin)
+ {
+ throw new UnsupportedOperationException(
+ "Can't add submodel interfaces to a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
+ }
+
+ @Override
+ protected void removeSubmodelInterface(String name)
+ {
+ throw new UnsupportedOperationException(
+ "Can't remove submodel interfaces of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
+ }
+
+ @Override
+ protected void setSize(double width, double height)
+ {
+ throw new UnsupportedOperationException(
+ "Can't set the size of a SimpleRectangularSubmodelComponent directly, call setInputPins / setOutputPins instead");
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.submodels;
+
+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;
+import net.haspamelodica.swt.helper.gcs.TranslatedGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.LogicUIRenderer;
+import net.mograsim.logic.ui.model.ViewModel;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.GUIWire;
+import net.mograsim.logic.ui.model.wires.MovablePin;
+import net.mograsim.logic.ui.model.wires.Pin;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerPinParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerWireParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InterfacePinParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
+
+/**
+ * A {@link GUIComponent} consisting of another model. A <code>SubmodelComponent</code> can have so-called "interface pins" connecting the
+ * inner and outer models.
+ */
+public abstract class SubmodelComponent extends GUIComponent
+{
+ /**
+ * A modifiable view of {@link #submodel}.
+ */
+ protected final ViewModelModifiable submodelModifiable;
+ /**
+ * The model this {@link SubmodelComponent} consists of.
+ */
+ public final ViewModel submodel;
+ /**
+ * The list of all submodel interface pins of this {@link SubmodelComponent} on the submodel side.
+ */
+ private final Map<String, MovablePin> submodelPins;
+ /**
+ * An unmodifiable view of {@link #submodelPins}.
+ */
+ private final Map<String, MovablePin> submodelMovablePinsUnmodifiable;
+ /**
+ * An unmodifiable view of {@link #submodelPins} where pins are not movable.
+ */
+ private final Map<String, Pin> submodelUnmovablePinsUnmodifiable;
+ /**
+ * The list of all submodel interface pins of this {@link SubmodelComponent} on the supermodel side.
+ */
+ private final Map<String, MovablePin> supermodelPins;
+ /**
+ * An unmodifiable view of {@link #supermodelPins}.
+ */
+ private final Map<String, MovablePin> supermodelMovablePinsUnmodifiable;
+ /**
+ * An unmodifiable view of {@link #supermodelPins} where pins are not movable.
+ */
+ private final Map<String, Pin> supermodelUnmovablePinsUnmodifiable;
+ /**
+ * A pseudo-component containing all submodel interface pins on the submodel side.
+ */
+ 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.
+ */
+ private double submodelScale;
+ /**
+ * If this {@link SubmodelComponent} fills at least this amount of the visible region vertically or horizontally, the submodel starts to
+ * be visible.
+ */
+ private double maxVisibleRegionFillRatioForAlpha0;
+ /**
+ * If this {@link SubmodelComponent} fills at least this amount of the visible region vertically or horizontally, the submodel is fully
+ * visible.
+ */
+ private double minVisibleRegionFillRatioForAlpha1;
+ /**
+ * The renderer used for rendering the submodel.
+ */
+ private final LogicUIRenderer renderer;
+
+ // creation and destruction
+
+ public SubmodelComponent(ViewModelModifiable model)
+ {
+ super(model);
+ this.submodelModifiable = new ViewModelModifiable();
+ this.submodel = submodelModifiable;
+ this.submodelPins = new HashMap<>();
+ this.submodelMovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins);
+ this.submodelUnmovablePinsUnmodifiable = Collections.unmodifiableMap(submodelPins);
+ this.supermodelPins = new HashMap<>();
+ this.supermodelMovablePinsUnmodifiable = Collections.unmodifiableMap(supermodelPins);
+ 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;
+ this.renderer = new LogicUIRenderer(submodelModifiable);
+
+ submodelModifiable.addRedrawListener(this::requestRedraw);
+ }
+
+ // pins
+
+ /**
+ * Adds a new submodel interface pin.
+ *
+ * @param supermodelPin the submodel interface pin on the supermodel side
+ *
+ * @return the submodel interface pin on the submodel side
+ *
+ * @author Daniel Kirschten
+ */
+ protected Pin addSubmodelInterface(MovablePin supermodelPin)
+ {
+ super.addPin(supermodelPin);// do this first to be fail-fast if the supermodel does not belong to this component
+
+ String name = supermodelPin.name;
+ MovablePin submodelPin = new MovablePin(submodelInterface, name, supermodelPin.logicWidth, supermodelPin.getRelX() / submodelScale,
+ supermodelPin.getRelY() / submodelScale);
+
+ submodelPin.addPinMovedListener(p ->
+ {
+ double newRelX = p.getRelX() * submodelScale;
+ double newRelY = p.getRelY() * submodelScale;
+ if (supermodelPin.getRelX() != newRelX || supermodelPin.getRelY() != newRelY)
+ supermodelPin.setRelPos(newRelX, newRelY);
+ });
+ supermodelPin.addPinMovedListener(p ->
+ {
+ double newRelX = p.getRelX() / submodelScale;
+ double newRelY = p.getRelY() / submodelScale;
+ if (submodelPin.getRelX() != newRelX || submodelPin.getRelY() != newRelY)
+ submodelPin.setRelPos(newRelX, newRelY);
+ });
+
+ submodelInterface.addPin(submodelPin);
+
+ submodelPins.put(name, submodelPin);
+ supermodelPins.put(name, supermodelPin);
+
+ // no need to call requestRedraw() because addPin() will request a redraw
+ return submodelPin;
+ }
+
+ /**
+ * Removes a submodel interface pin.
+ *
+ * @author Daniel Kirschten
+ */
+ protected void removeSubmodelInterface(String name)
+ {
+ super.removePin(name);// do this first to be fail-fast if this component doesn't have a pin with the given name
+ Pin submodelPin = submodelPins.remove(name);
+ submodelInterface.removePin(submodelPin.name);
+ supermodelPins.remove(name);
+
+ // no need to call requestRedraw() because removePin() will request a redraw
+ }
+
+ /**
+ * Returns a collection of submodel interface pins on the submodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ public Map<String, Pin> getSubmodelPins()
+ {
+ return submodelUnmovablePinsUnmodifiable;
+ }
+
+ /**
+ * Returns the submodel interface pin with the given name on the submodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ public Pin getSubmodelPin(String name)
+ {
+ return getSubmodelMovablePin(name);
+ }
+
+ /**
+ * Returns a collection of movable submodel interface pins on the submodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ protected Map<String, MovablePin> getSubmodelMovablePins()
+ {
+ return submodelMovablePinsUnmodifiable;
+ }
+
+ /**
+ * Returns the movable submodel interface pin with the given name on the submodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ protected MovablePin getSubmodelMovablePin(String name)
+ {
+ return submodelPins.get(name);
+ }
+
+ /**
+ * Returns a collection of submodel interface pins on the supermodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ public Map<String, Pin> getSupermodelPins()
+ {
+ return supermodelUnmovablePinsUnmodifiable;
+ }
+
+ /**
+ * Returns the submodel interface pin with the given name on the supermodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ public Pin getSupermodelPin(String name)
+ {
+ return getSupermodelMovablePin(name);
+ }
+
+ /**
+ * Returns a collection of movable submodel interface pins on the supermodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ protected Map<String, MovablePin> getSupermodelMovablePins()
+ {
+ return supermodelMovablePinsUnmodifiable;
+ }
+
+ /**
+ * Returns the movable submodel interface pin with the given name on the supermodel side of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ protected MovablePin getSupermodelMovablePin(String name)
+ {
+ 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
+
+ /**
+ * Sets the factor by which the submodel is scaled when rendering and calls redrawListeners. Note that the submodel interface pins will
+ * stay at their position relative to the supermodel, which means they will move relative to the submodel.
+ *
+ * @author Daniel Kirschten
+ */
+ protected void setSubmodelScale(double submodelScale)
+ {
+ this.submodelScale = submodelScale;
+
+ for (Entry<String, MovablePin> e : supermodelPins.entrySet())
+ getSubmodelMovablePin(e.getKey()).setRelPos(e.getValue().getRelX() * submodelScale, e.getValue().getRelY() * submodelScale);
+
+ requestRedraw();// needed if there is no submodel interface pin
+ }
+
+ /**
+ * Returns the current factor by which the submodel is scaled when rendering.
+ *
+ * @author Daniel Kirschten
+ */
+ protected double getSubmodelScale()
+ {
+ return submodelScale;
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {
+ GCConfig conf = new GCConfig(gc);
+ TranslatedGC tgc = new TranslatedGC(gc, getPosX(), getPosY(), submodelScale, true);
+ conf.reset(tgc);
+ double visibleRegionFillRatio = Math.max(getWidth() / visibleRegion.width, getHeight() / visibleRegion.height);
+ double alphaFactor = map(visibleRegionFillRatio, maxVisibleRegionFillRatioForAlpha0, minVisibleRegionFillRatioForAlpha1, 0, 1);
+ alphaFactor = Math.max(0, Math.min(1, alphaFactor));
+ // we need to take the old alpha into account to support nested submodules better.
+ int oldAlpha = gc.getAlpha();
+ int submodelAlpha = Math.max(0, Math.min(255, (int) (oldAlpha * alphaFactor)));
+ int labelAlpha = Math.max(0, Math.min(255, (int) (oldAlpha * (1 - alphaFactor))));
+ if (submodelAlpha != 0)
+ {
+ gc.setAlpha(submodelAlpha);
+ renderer.render(tgc, visibleRegion.translate(getPosX() / submodelScale, getPosY() / submodelScale, 1 / submodelScale));
+ }
+ if (labelAlpha != 0)
+ {
+ gc.setAlpha(labelAlpha);
+ renderSymbol(gc, visibleRegion);
+ }
+ conf.reset(gc);
+ // draw the outline after all other operations to make interface pins look better
+ renderOutline(gc, visibleRegion);
+ }
+
+ // TODO make this a path
+ /**
+ * 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 mapMin + (val - valMin) * (mapMax - mapMin) / (valMax - valMin);
+ }
+
+ @Override
+ public boolean clicked(double x, double y)
+ {
+ double scaledX = (x - getPosX()) / submodelScale;
+ double scaledY = (y - getPosY()) / submodelScale;
+ for (GUIComponent component : submodel.getComponents())
+ if (component.getBounds().contains(scaledX, scaledY) && component.clicked(scaledX, scaledY))
+ return true;
+ return false;
+ }
+
+ // serializing
+
+ /**
+ * @return {@link SubmodelComponentParams}, which describe this {@link SubmodelComponent}.
+ */
+ public SubmodelComponentParams calculateParams()
+ {
+ SubmodelComponentParams params = new SubmodelComponentParams();
+ params.name = getIdentifier();
+ params.type = SubmodelComponent.class.getSimpleName();
+ params.composition = calculateCompositionParams();
+
+ params.width = getWidth();
+ params.height = getHeight();
+
+ InterfacePinParams[] iPins = new InterfacePinParams[getPins().size()];
+ int i = 0;
+ for (Pin p : getPins().values())
+ {
+ InterfacePinParams iPinParams = new InterfacePinParams();
+ iPins[i] = iPinParams;
+ iPinParams.location = p.getRelPos();
+ iPinParams.name = p.name;
+ iPinParams.logicWidth = p.logicWidth;
+ i++;
+ }
+ params.interfacePins = iPins;
+ return params;
+ }
+
+ protected ComponentCompositionParams calculateCompositionParams()
+ {
+ ComponentCompositionParams params = new ComponentCompositionParams();
+ params.innerScale = getSubmodelScale();
+
+ List<GUIComponent> compList = submodelModifiable.getComponents();
+ Iterator<GUIComponent> componentIt = compList.iterator();
+ componentIt.next(); // Skip inner SubmodelInterface
+ InnerComponentParams[] comps = new InnerComponentParams[compList.size() - 1];
+ int i = 0;
+ while (componentIt.hasNext())
+ {
+ GUIComponent component = componentIt.next();
+ InnerComponentParams inner = new InnerComponentParams();
+ comps[i] = inner;
+ inner.params = component.getInstantiationParameters();
+ inner.pos = new Point(component.getPosX(), component.getPosY());
+ inner.name = component.getIdentifier();
+ i++;
+ }
+ params.subComps = comps;
+
+ List<GUIWire> wireList = submodelModifiable.getWires();
+ InnerWireParams wires[] = new InnerWireParams[wireList.size()];
+ i = 0;
+ for (GUIWire wire : wireList)
+ {
+ InnerWireParams inner = new InnerWireParams();
+ wires[i] = inner;
+ InnerPinParams pin1Params = new InnerPinParams(), pin2Params = new InnerPinParams();
+
+ pin1Params.pinName = wire.getPin1().name;
+ pin1Params.compId = compList.indexOf(wire.getPin1().component);
+ pin2Params.pinName = wire.getPin2().name;
+ pin2Params.compId = compList.indexOf(wire.getPin2().component);
+ inner.pin1 = pin1Params;
+ inner.pin2 = pin2Params;
+ inner.path = wire.getPath();
+ i++;
+ }
+ params.innerWires = wires;
+ return params;
+ }
+
+ // operations no longer supported
+
+ @Override
+ protected void addPin(Pin pin)
+ {
+ throw new UnsupportedOperationException("Can't add pins to a SubmodelComponent directly, call addSubmodelInterface instead");
+ }
+
+ @Override
+ protected void removePin(String name)
+ {
+ throw new UnsupportedOperationException("Can't remove pins of a SubmodelComponent directly, call removeSubmodelInterface instead");
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.model.components.submodels;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.Pin;
+
+public class SubmodelInterface extends GUIComponent
+{
+ public SubmodelInterface(ViewModelModifiable model)
+ {
+ super(model);
+ }
+
+ @Override
+ public void render(GeneralGC gc, Rectangle visibleRegion)
+ {// nothing to do here
+ }
+
+ /**
+ * {@inheritDoc}<br>
+ * This method is only marked public in {@link SubmodelInterface} for {@link SubmodelComponent} to be able to add / remove pins to /
+ * from a SubmodelInterface.<br>
+ *
+ * @see GUIComponent#removePin(Pin)
+ *
+ * @author Daniel Kirschten
+ */
+ @Override
+ public void addPin(Pin pin)
+ {
+ super.addPin(pin);
+ }
+
+ /**
+ * {@inheritDoc}<br>
+ * This method is only marked public in {@link SubmodelInterface} for {@link SubmodelComponent} to be able to add / remove pins to /
+ * from a SubmodelInterface.<br>
+ *
+ * @see GUIComponent#removePin(Pin)
+ *
+ * @author Daniel Kirschten
+ */
+ @Override
+ protected void removePin(String name)
+ {
+ super.removePin(name);
+ }
+}
\ No newline at end of file
import net.mograsim.logic.ui.ColorHelper;
import net.mograsim.logic.ui.model.ViewModelModifiable;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.SimpleRectangularGUIGate;
+import net.mograsim.logic.ui.model.components.atomic.SimpleRectangularGUIGate;
/**
* A {@link GUIComponent} with only one pin. Is used to create wires connecting more than two pins. <br>
import net.mograsim.logic.core.wires.Wire.ReadEnd;
import net.mograsim.logic.ui.model.ViewModel;
import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.components.SubmodelComponent;
-import net.mograsim.logic.ui.model.components.SubmodelInterface;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelInterface;
import net.mograsim.logic.ui.model.wires.GUIWire;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.model.wires.WireCrossPoint;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.wires.Wire;
import net.mograsim.logic.core.wires.Wire.ReadEnd;
-import net.mograsim.logic.ui.model.components.GUIBitDisplay;
+import net.mograsim.logic.ui.model.components.atomic.GUIBitDisplay;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.modeladapter.LogicModelParameters;
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.wires.Wire;
import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-import net.mograsim.logic.ui.model.components.GUIManualSwitch;
+import net.mograsim.logic.ui.model.components.atomic.GUIManualSwitch;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.modeladapter.LogicModelParameters;
import net.mograsim.logic.core.wires.Wire;
import net.mograsim.logic.core.wires.Wire.ReadEnd;
import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-import net.mograsim.logic.ui.model.components.SimpleRectangularGUIGate;
+import net.mograsim.logic.ui.model.components.atomic.SimpleRectangularGUIGate;
import net.mograsim.logic.ui.model.wires.Pin;
import net.mograsim.logic.ui.modeladapter.LogicModelParameters;
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.util.function.Supplier;
+
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
+
+/**
+ * A {@link SimpleRectangularSubmodelComponent} which was created by deserializing a JSON file.
+ *
+ * @author Daniel Kirschten
+ */
+public class DeserializedSimpleRectangularSubmodelComponent extends SimpleRectangularSubmodelComponent
+ implements DeserializedSubmodelComponentI
+{
+ public DeserializedSimpleRectangularSubmodelComponent(ViewModelModifiable model, int logicWidth, String label)
+ {
+ super(model, logicWidth, label);
+ }
+
+ @Override
+ public ViewModelModifiable getSubmodelModifiable()
+ {
+ return submodelModifiable;
+ }
+
+ @Override
+ public void setIdentifierDelegate(Supplier<String> identifierDelegate)
+ {
+ this.identifierDelegate = identifierDelegate;
+ }
+
+ @Override
+ public void setSubmodelScale(double submodelScale)
+ {
+ super.setSubmodelScale(submodelScale);
+ }
+
+ @Override
+ public void setInputPins(String... pinNames)
+ {
+ super.setInputPins(pinNames);
+ }
+
+ @Override
+ public void setOutputPins(String... pinNames)
+ {
+ super.setOutputPins(pinNames);
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.util.function.Supplier;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.ui.model.wires.MovablePin;
+import net.mograsim.logic.ui.model.wires.Pin;
+
+public class DeserializedSubmodelComponent extends SubmodelComponent implements DeserializedSubmodelComponentI
+{
+ public DeserializedSubmodelComponent(ViewModelModifiable model)
+ {
+ super(model);
+ }
+
+ @Override
+ protected void renderOutline(GeneralGC gc, Rectangle visibleRegion)
+ {
+ // TODO
+ }
+
+ @Override
+ protected void renderSymbol(GeneralGC gc, Rectangle visibleRegion)
+ {
+ // TODO
+ }
+
+ @Override
+ public ViewModelModifiable getSubmodelModifiable()
+ {
+ return submodelModifiable;
+ }
+
+ @Override
+ public void setIdentifierDelegate(Supplier<String> identifierDelegate)
+ {
+ this.identifierDelegate = identifierDelegate;
+ }
+
+ @Override
+ public void setSubmodelScale(double submodelScale)
+ {
+ super.setSubmodelScale(submodelScale);
+ }
+
+ @Override
+ public void setSize(double width, double height)
+ {
+ super.setSize(width, height);
+ }
+
+ @Override
+ protected Pin addSubmodelInterface(MovablePin supermodelPin)
+ {
+ return super.addSubmodelInterface(supermodelPin);
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.util.function.Supplier;
+
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+
+/**
+ * A {@link SubmodelComponent} which was created by deserializing a JSON file.
+ *
+ * @author Daniel Kirschten
+ */
+public interface DeserializedSubmodelComponentI
+{
+ public ViewModelModifiable getSubmodelModifiable();
+
+ /**
+ * Sets the identifier delegate used by this deserialized component.
+ *
+ * @author Daniel Kirschten
+ */
+ public void setIdentifierDelegate(Supplier<String> identifierDelegate);
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.components.atomic.SimpleRectangularGUIGate;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.wires.WireCrossPoint;
+import net.mograsim.logic.ui.util.JsonHandler;
+
+public class IndirectGUIComponentCreator
+{
+ private final static Map<String, String> componentMapping;
+
+ static
+ {
+ Map<String, String> tmp;
+ try (InputStream s = IndirectGUIComponentCreator.class.getResourceAsStream("./mapping.json"))
+ {
+ tmp = JsonHandler.readJson(s, Map.class);
+ }
+ catch (IOException e)
+ {
+ System.err.println("Failed to initialize component mapping; Components cannot be created from file.");
+ e.printStackTrace();
+ tmp = new HashMap<>();
+ }
+ componentMapping = tmp;
+ }
+
+ public static GUIComponent create(ViewModelModifiable model, String name, Map<String, Object> params)
+ {
+ try
+ {
+ String path = componentMapping.get(name);
+ if (path.startsWith("class:"))
+ {
+ path = path.substring(6);
+ return createComponentFromClass(model, path, params);
+ } else if (path.startsWith("file:"))
+ {
+ path = path.substring(5);
+ return SubmodelComponentDeserializer.create(model, path);
+ } else
+ throw new IllegalArgumentException("Invalid submodel type! Type was neither prefixed by 'class:' nor by 'file:'");
+ }
+ catch (NullPointerException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
+ | SecurityException | ClassNotFoundException | IllegalArgumentException e)
+ {
+ System.err.println("Failed to create requested component!");
+ e.printStackTrace();
+ return new SimpleRectangularSubmodelComponent(model, 1, "ERROR");
+ }
+ }
+
+ private static GUIComponent createComponentFromClass(ViewModelModifiable model, String classname, Map<String, Object> params)
+ throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException,
+ ClassNotFoundException
+ {
+ Class<?> c = Class.forName(classname);
+ Object comp;
+ if (SimpleRectangularGUIGate.class.isAssignableFrom(c) || WireCrossPoint.class.equals(c))
+ {
+ Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class, int.class);
+ comp = constructor.newInstance(model, ((Number) params.get(SimpleRectangularGUIGate.kLogicWidth)).intValue());
+ } else
+ {
+ Constructor<?> constructor = c.getConstructor(ViewModelModifiable.class);
+ comp = constructor.newInstance(model);
+ }
+ return (GUIComponent) comp;
+ }
+}
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+import net.mograsim.logic.ui.model.ViewModelModifiable;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.components.submodels.SimpleRectangularSubmodelComponent;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.ui.model.wires.GUIWire;
+import net.mograsim.logic.ui.model.wires.MovablePin;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InnerWireParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.InterfacePinParams;
+import net.mograsim.logic.ui.serializing.SubmodelComponentParams.ComponentCompositionParams.InnerComponentParams;
+
+/**
+ * Creates {@link SubmodelComponent}s from {@link SubmodelComponentParams}
+ */
+public final class SubmodelComponentDeserializer
+{
+ private static final String rectC = SimpleRectangularSubmodelComponent.class.getSimpleName();
+
+ /**
+ * Creates a {@link SubmodelComponent} from the {@link SubmodelComponentParams}, specified at the given path. The returned
+ * SubmodelComponent can also be e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the
+ * {@link SubmodelComponentParams} describe.
+ *
+ * @param path The path of the file describing the {@link SubmodelComponentParams}, which define the new {@link SubmodelComponent}
+ * @return A new SubmodelComponent, as described in the file located at the given path
+ */
+ public static SubmodelComponent create(ViewModelModifiable model, String path)
+ {
+ try
+ {
+ SubmodelComponentParams params = SubmodelComponentParams.readJson(path);
+ SubmodelComponent ret = create(model, params);
+ return ret;
+ }
+ catch (IOException e)
+ {
+ System.err.println("Failed to construct GUICustomComponent. Parameters were not found.");
+ e.printStackTrace();
+ }
+ return new SimpleRectangularSubmodelComponent(model, 0, "ERROR");
+ }
+
+ /**
+ * Creates a {@link SubmodelComponent} from the specified {@link SubmodelComponentParams}. The returned SubmodelComponent can also be
+ * e.g. a {@link SimpleRectangularSubmodelComponent}, depending on what the {@link SubmodelComponentParams} describe.
+ *
+ * @param params The parameters describing the {@link SubmodelComponent}
+ *
+ * @return A new SubmodelComponent, as described by the {@link SubmodelComponentParams}
+ */
+ public static SubmodelComponent create(ViewModelModifiable model, SubmodelComponentParams params)
+ {
+ DeserializedSubmodelComponentI comp = null;
+ if (rectC.equals(params.type))
+ {
+ comp = createRectComponent(model, params);
+ }
+
+ if (comp == null)
+ {
+ comp = createSubmodelComponent(model, params);
+ }
+ comp.setIdentifierDelegate(() -> params.name);
+ initInnerComponents(comp, params.composition);
+ return (SubmodelComponent) comp;
+ }
+
+ // May return null
+ @SuppressWarnings("unchecked")
+ private static DeserializedSimpleRectangularSubmodelComponent createRectComponent(ViewModelModifiable model,
+ SubmodelComponentParams params)
+ {
+ try
+ {
+ Map<String, Object> m = params.specialized;
+ DeserializedSimpleRectangularSubmodelComponent rect = new DeserializedSimpleRectangularSubmodelComponent(model,
+ ((Number) m.get(SimpleRectangularSubmodelComponent.kLogicWidth)).intValue(),
+ (String) m.get(SimpleRectangularSubmodelComponent.kLabel));
+ rect.setSubmodelScale(params.composition.innerScale);
+
+ Object[] names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kInCount)).toArray();
+ rect.setInputPins(Arrays.copyOf(names, names.length, String[].class));
+
+ names = ((ArrayList<Object>) m.get(SimpleRectangularSubmodelComponent.kOutCount)).toArray();
+ rect.setOutputPins(Arrays.copyOf(names, names.length, String[].class));
+
+ return rect;
+ }
+ catch (ClassCastException | NullPointerException e)
+ {
+ System.err.println("Failed to specialize component!");
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private static DeserializedSubmodelComponent createSubmodelComponent(ViewModelModifiable model, SubmodelComponentParams params)
+ {
+ DeserializedSubmodelComponent comp = new DeserializedSubmodelComponent(model);
+ comp.setSubmodelScale(params.composition.innerScale);
+ comp.setSize(params.width, params.height);
+ for (InterfacePinParams iPinParams : params.interfacePins)
+ {
+ comp.addSubmodelInterface(
+ new MovablePin(comp, iPinParams.name, iPinParams.logicWidth, iPinParams.location.x, iPinParams.location.y));
+ }
+ return comp;
+ }
+
+ @SuppressWarnings("unused")
+ private static void initInnerComponents(DeserializedSubmodelComponentI comp, ComponentCompositionParams params)
+ {
+ GUIComponent[] components = new GUIComponent[params.subComps.length];
+ for (int i = 0; i < components.length; i++)
+ {
+ InnerComponentParams cParams = params.subComps[i];
+ String path = cParams.name;
+ components[i] = IndirectGUIComponentCreator.create(comp.getSubmodelModifiable(), cParams.name, cParams.params);
+ components[i].moveTo(cParams.pos.x, cParams.pos.y);
+ }
+
+ for (int i = 0; i < params.innerWires.length; i++)
+ {
+ InnerWireParams innerWire = params.innerWires[i];
+ new GUIWire(comp.getSubmodelModifiable(),
+ comp.getSubmodelModifiable().getComponents().get(innerWire.pin1.compId).getPin(innerWire.pin1.pinName),
+ comp.getSubmodelModifiable().getComponents().get(innerWire.pin2.compId).getPin(innerWire.pin2.pinName), innerWire.path);
+ }
+ }
+}
--- /dev/null
+package net.mograsim.logic.ui.serializing;
+
+import java.io.IOException;
+import java.util.Map;
+
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.mograsim.logic.ui.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.ui.util.JsonHandler;
+
+/**
+ * This class contains all the information necessary to create a new {@link SubmodelComponent}
+ */
+public class SubmodelComponentParams
+{
+ public String type, name;
+ public double width, height;
+ public InterfacePinParams[] interfacePins;
+ public ComponentCompositionParams composition;
+ public Map<String, Object> specialized;
+
+ public static class InterfacePinParams
+ {
+ public Point location;
+ public String name;
+ public int logicWidth;
+ }
+
+ public static class InnerWireParams
+ {
+ public InnerPinParams pin1, pin2;
+ public Point[] path;
+ }
+
+ public static class InnerPinParams
+ {
+ public int compId;
+ public String pinName;
+ }
+
+ public static class ComponentCompositionParams
+ {
+ public double innerScale;
+ public InnerComponentParams[] subComps;
+ public InnerWireParams[] innerWires;
+
+ public static class InnerComponentParams
+ {
+ public Point pos;
+ public String name;
+ public Map<String, Object> params;
+ }
+ }
+
+ public static SubmodelComponentParams readJson(String path) throws IOException
+ {
+ return JsonHandler.readJson(path, SubmodelComponentParams.class);
+ }
+
+ /**
+ * Writes this {@link SubmodelComponentParams} object into a file in json format. The correct file extension is important! Check
+ * {@link SubmodelComponentParams}.fileExtension
+ */
+ public void writeJson(String path)
+ {
+ try
+ {
+ JsonHandler.writeJson(this, path);
+ }
+ catch (IOException e)
+ {
+ System.err.println("Failed to write SubComponentParams to file");
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+mograsim version: 0.1.2
+{
+ "GUIAm2901": "file:components/am2901/GUIAm2901.json",
+ "GUIAm2901ALUFuncDecode": "file:components/am2901/GUIAm2901ALUFuncDecode.json",
+ "GUIAm2901ALUInclDecode": "file:components/am2901/GUIAm2901ALUInclDecode.json",
+ "GUIAm2901ALUInclSourceDecodeInclFunctionDecode": "file:components/am2901/GUIAm2901ALUInclSourceDecodeInclFunctionDecode.json",
+ "GUIAm2901ALUOneBit": "file:components/am2901/GUIAm2901ALUOneBit.json",
+ "GUIAm2901DestDecode": "file:components/am2901/GUIAm2901DestDecode.json",
+ "GUIAm2901QReg": "file:components/am2901/GUIAm2901QReg.json",
+ "GUIAm2901SourceDecode": "file:components/am2901/GUIAm2901SourceDecode.json",
+ "GUIAndGate": "class:net.mograsim.logic.ui.model.components.GUIAndGate",
+ "GUINandGate": "class:net.mograsim.logic.ui.model.components.GUINandGate",
+ "GUIOrGate": "class:net.mograsim.logic.ui.model.components.GUIOrGate",
+ "GUI_rsLatch": "file:components/GUI_rsLatch.json",
+ "GUIand": "file:components/GUIand.json",
+ "GUIand41": "file:components/GUIand41.json",
+ "GUIandor414": "file:components/GUIandor414.json",
+ "GUIdemux2": "file:components/GUIdemux2.json",
+ "GUIdff": "file:components/GUIdff.json",
+ "GUIdlatch": "file:components/GUIdlatch.json",
+ "GUIdlatch4": "file:components/GUIdlatch4.json",
+ "GUIfulladder": "file:components/GUIfulladder.json",
+ "GUIhalfadder": "file:components/GUIhalfadder.json",
+ "GUImux1": "file:components/GUImux1.json",
+ "GUImux1_4": "file:components/GUImux1_4.json",
+ "GUInand3": "file:components/GUInand3.json",
+ "GUInot4": "file:components/GUInot4.json",
+ "GUIor4": "file:components/GUIor4.json",
+ "GUIor_4": "file:components/GUIor_4.json",
+ "GUIram2": "file:components/GUIram2.json",
+ "GUIram4": "file:components/GUIram4.json",
+ "GUIsel2_4": "file:components/GUIsel2_4.json",
+ "GUIsel3_4": "file:components/GUIsel3_4.json",
+ "GUIxor": "file:components/GUIxor.json",
+ "WireCrossPoint": "class:net.mograsim.logic.ui.model.wires.WireCrossPoint"
+}
\ No newline at end of file