Suppressed warnings where the thing warned about is intentional
[Mograsim.git] / LogicUI / src / era / mi / gui / modeladapter / ViewLogicModelAdapter.java
index d159b60..1e7d341 100644 (file)
@@ -14,12 +14,18 @@ import java.util.stream.Collectors;
 import era.mi.gui.model.ViewModel;
 import era.mi.gui.model.components.GUIAndGate;
 import era.mi.gui.model.components.GUIComponent;
+import era.mi.gui.model.components.GUINotGate;
+import era.mi.gui.model.components.GUIOrGate;
 import era.mi.gui.model.wires.GUIWire;
 import era.mi.gui.model.wires.Pin;
 import era.mi.gui.model.wires.WireCrossPoint;
-import era.mi.gui.modeladapter.componentadapters.AndGateAdapter;
 import era.mi.gui.modeladapter.componentadapters.ComponentAdapter;
+import era.mi.gui.modeladapter.componentadapters.ManualSwitchAdapter;
+import era.mi.gui.modeladapter.componentadapters.SimpleGateAdapter;
 import era.mi.logic.components.Component;
+import era.mi.logic.components.gates.AndGate;
+import era.mi.logic.components.gates.NotGate;
+import era.mi.logic.components.gates.OrGate;
 import era.mi.logic.timeline.Timeline;
 import era.mi.logic.wires.Wire;
 import era.mi.logic.wires.Wire.ReadEnd;
@@ -29,10 +35,14 @@ public class ViewLogicModelAdapter
        private final static Map<Class<? extends GUIComponent>, ComponentAdapter<? extends GUIComponent>> componentAdapters;
        static
        {
-               Map<Class<? extends GUIComponent>, ComponentAdapter<? extends GUIComponent>> componentAdaptersModifiable = new HashMap<>();
-               componentAdaptersModifiable.put(GUIAndGate.class, new AndGateAdapter());
+               Set<ComponentAdapter<? extends GUIComponent>> componentAdaptersModifiable = new HashSet<>();
+               componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUIOrGate.class, OrGate::new));
+               componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUIAndGate.class, AndGate::new));
+               componentAdaptersModifiable.add(new SimpleGateAdapter<>(GUINotGate.class, (t, p, o, i) -> new NotGate(t, p, i[0], o)));
+               componentAdaptersModifiable.add(new ManualSwitchAdapter());
                // TODO list all "primitive" adapters here
-               componentAdapters = Collections.unmodifiableMap(componentAdaptersModifiable);
+               componentAdapters = Collections.unmodifiableMap(
+                               componentAdaptersModifiable.stream().collect(Collectors.toMap(ComponentAdapter::getSupportedClass, Function.identity())));
        }
 
        public static Timeline convert(ViewModel viewModel, LogicModelParameters params)
@@ -40,16 +50,22 @@ public class ViewLogicModelAdapter
                // TODO replace Timeline with LogicModel as soon as it exists
                Timeline timeline = new Timeline(10);
 
-               Map<Pin, Wire> logicWiresPerPin = convertWires(viewModel.getWires(), params, timeline);
+               Map<Pin, Wire> logicWiresPerPin = convertWires(
+                               viewModel.getComponents().stream().flatMap(component -> component.getPins().stream()).collect(Collectors.toSet()),
+                               viewModel.getWires(), params, timeline);
                Map<Pin, Wire> logicWiresPerPinUnmodifiable = Collections.unmodifiableMap(logicWiresPerPin);
 
                Map<GUIComponent, Component> oneToOneComponents = new HashMap<>();
                for (GUIComponent guiComp : viewModel.getComponents())
                {
-                       // WireCrossPoints just vanish
                        if (!(guiComp instanceof WireCrossPoint))
                                oneToOneComponents.put(guiComp, createAndLinkComponent(timeline, params, guiComp, logicWiresPerPinUnmodifiable,
                                                componentAdapters.get(guiComp.getClass())));
+                       else
+                       {
+                               WireCrossPoint guiCompCasted = (WireCrossPoint) guiComp;
+                               guiCompCasted.setLogicModelBinding(logicWiresPerPin.get(guiCompCasted.getPin()).createReadOnlyEnd());
+                       }
                }
 
                // TODO handle complex components
@@ -60,9 +76,9 @@ public class ViewLogicModelAdapter
                return timeline;
        }
 
-       private static Map<Pin, Wire> convertWires(List<GUIWire> wires, LogicModelParameters params, Timeline timeline)
+       private static Map<Pin, Wire> convertWires(Set<Pin> allPins, List<GUIWire> wires, LogicModelParameters params, Timeline timeline)
        {
-               Map<Pin, Set<Pin>> connectedPinGroups = getConnectedPinGroups(wires);
+               Map<Pin, Set<Pin>> connectedPinGroups = getConnectedPinGroups(allPins, wires);
                Map<Pin, Wire> logicWiresPerPin = createLogicWires(params, timeline, connectedPinGroups);
                setGUIWiresLogicModelBinding(wires, logicWiresPerPin);
                return logicWiresPerPin;
@@ -80,22 +96,30 @@ public class ViewLogicModelAdapter
 
        private static void setGUIWiresLogicModelBinding(List<GUIWire> wires, Map<Pin, Wire> logicWiresPerPin)
        {
-               Map<Wire, ReadEnd> guiWireSharedReadEnd = logicWiresPerPin.values().stream()
+               Map<Wire, ReadEnd> guiWireSharedReadEnd = logicWiresPerPin.values().stream().distinct()
                                .collect(Collectors.toMap(Function.identity(), Wire::createReadOnlyEnd));
                for (GUIWire guiWire : wires)
                        guiWire.setLogicModelBinding(guiWireSharedReadEnd.get(logicWiresPerPin.get(guiWire.getPin1())));
        }
 
-       private static Map<Pin, Set<Pin>> getConnectedPinGroups(List<GUIWire> wires)
+       private static Map<Pin, Set<Pin>> getConnectedPinGroups(Set<Pin> allPins, List<GUIWire> wires)
        {
                Map<Pin, Set<Pin>> connectedPinsPerPin = new HashMap<>();
+
+               for (Pin p : allPins)
+               {
+                       HashSet<Pin> connectedPins = new HashSet<>();
+                       connectedPins.add(p);
+                       connectedPinsPerPin.put(p, connectedPins);
+               }
+
                wires.forEach(wire ->
                {
                        Pin pin1 = wire.getPin1();
                        Pin pin2 = wire.getPin2();
 
-                       Set<Pin> pin1ConnectedPins = connectedPinsPerPin.putIfAbsent(pin1, new HashSet<>());
-                       Set<Pin> pin2ConnectedPins = connectedPinsPerPin.putIfAbsent(pin2, new HashSet<>());
+                       Set<Pin> pin1ConnectedPins = connectedPinsPerPin.get(pin1);
+                       Set<Pin> pin2ConnectedPins = connectedPinsPerPin.get(pin2);
 
                        pin1ConnectedPins.addAll(pin2ConnectedPins);
                        pin1ConnectedPins.add(pin1);
@@ -110,6 +134,8 @@ public class ViewLogicModelAdapter
        private static <G extends GUIComponent> Component createAndLinkComponent(Timeline timeline, LogicModelParameters params,
                        GUIComponent guiComponent, Map<Pin, Wire> logicWiresPerPin, ComponentAdapter<G> adapter)
        {
+               if (adapter == null)
+                       throw new IllegalArgumentException("Unknown component class: " + guiComponent.getClass());
                return adapter.createAndLinkComponent(timeline, params, (G) guiComponent, logicWiresPerPin);
        }