X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.ui%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fui%2Fmodeladapter%2FViewLogicModelAdapter.java;h=cedb12799541915f63991fbfee1f8e2d962ba7c7;hb=fd422eab477a9e63b7db45a5d0e899373a2856a0;hp=3f05964eb140d38ee8c09ada39b3c1393b24761c;hpb=0cd1108bde5620d8d38001caea12471db3a5e633;p=Mograsim.git diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/modeladapter/ViewLogicModelAdapter.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/modeladapter/ViewLogicModelAdapter.java index 3f05964e..cedb1279 100644 --- a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/modeladapter/ViewLogicModelAdapter.java +++ b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/modeladapter/ViewLogicModelAdapter.java @@ -1,53 +1,34 @@ package net.mograsim.logic.ui.modeladapter; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import net.mograsim.logic.core.components.Component; -import net.mograsim.logic.core.components.gates.AndGate; -import net.mograsim.logic.core.components.gates.NotGate; -import net.mograsim.logic.core.components.gates.OrGate; 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.ViewModel; -import net.mograsim.logic.ui.model.components.GUIAndGate; import net.mograsim.logic.ui.model.components.GUIComponent; -import net.mograsim.logic.ui.model.components.GUINotGate; -import net.mograsim.logic.ui.model.components.GUIOrGate; +import net.mograsim.logic.ui.model.components.SubmodelComponent; +import net.mograsim.logic.ui.model.components.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.ui.modeladapter.componentadapters.Am2901NANDBasedAdapter; -import net.mograsim.logic.ui.modeladapter.componentadapters.BitDisplayAdapter; import net.mograsim.logic.ui.modeladapter.componentadapters.ComponentAdapter; -import net.mograsim.logic.ui.modeladapter.componentadapters.ManualSwitchAdapter; -import net.mograsim.logic.ui.modeladapter.componentadapters.SimpleGateAdapter; public class ViewLogicModelAdapter { - private final static Map, ComponentAdapter> componentAdapters; - static + private final static Map, ComponentAdapter> componentAdapters = new HashMap<>(); + + public static void addComponentAdapter(ComponentAdapter componentAdapter) { - Set> 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()); - componentAdaptersModifiable.add(new BitDisplayAdapter()); - componentAdaptersModifiable.add(new Am2901NANDBasedAdapter()); - // TODO list all "primitive" adapters here - componentAdapters = Collections.unmodifiableMap( - componentAdaptersModifiable.stream().collect(Collectors.toMap(ComponentAdapter::getSupportedClass, Function.identity()))); + componentAdapters.put(componentAdapter.getSupportedClass(), componentAdapter); } public static Timeline convert(ViewModel viewModel, LogicModelParameters params) @@ -55,48 +36,71 @@ public class ViewLogicModelAdapter // TODO replace Timeline with LogicModel as soon as it exists Timeline timeline = new Timeline(10); - Map logicWiresPerPin = convertWires( - viewModel.getComponents().stream().flatMap(component -> component.getPins().stream()).collect(Collectors.toSet()), - viewModel.getWires(), params, timeline); + convert(viewModel, params, timeline, Map.of()); + + return timeline; + } + + private static void convert(ViewModel viewModel, LogicModelParameters params, Timeline timeline, Map externalWires) + { + Map logicWiresPerPin = convertWires(getAllPins(viewModel), viewModel.getWires(), externalWires, params, timeline); Map logicWiresPerPinUnmodifiable = Collections.unmodifiableMap(logicWiresPerPin); - Map oneToOneComponents = new HashMap<>(); for (GUIComponent guiComp : viewModel.getComponents()) { - if (!(guiComp instanceof WireCrossPoint)) - oneToOneComponents.put(guiComp, createAndLinkComponent(timeline, params, guiComp, logicWiresPerPinUnmodifiable, - componentAdapters.get(guiComp.getClass()))); - else + if (guiComp instanceof SubmodelComponent) + { + SubmodelComponent guiCompCasted = (SubmodelComponent) guiComp; + Map supermodelPins = guiCompCasted.getSupermodelPins(); + Map externalWiresForSubmodel = supermodelPins.entrySet().stream() + .collect(Collectors.toMap(e -> guiCompCasted.getSubmodelPin(e.getKey()), e -> logicWiresPerPin.get(e.getValue()))); + convert(guiCompCasted.submodel, params, timeline, externalWiresForSubmodel); + } else if (guiComp instanceof WireCrossPoint) { WireCrossPoint guiCompCasted = (WireCrossPoint) guiComp; guiCompCasted.setLogicModelBinding(logicWiresPerPin.get(guiCompCasted.getPin()).createReadOnlyEnd()); - } + } else if (!(guiComp instanceof SubmodelInterface))// nothing to do for SubmodelInterfaces + createAndLinkComponent(timeline, params, guiComp, logicWiresPerPinUnmodifiable, componentAdapters.get(guiComp.getClass())); } + } - // TODO handle complex components - - List logicComponents = new ArrayList<>(); - // null means "no one to one mapping" - oneToOneComponents.values().stream().filter(Objects::nonNull).forEach(logicComponents::add); - - return timeline; + private static Set getAllPins(ViewModel viewModel) + { + return viewModel.getComponents().stream().flatMap(component -> component.getPins().values().stream()).collect(Collectors.toSet()); } - private static Map convertWires(Set allPins, List wires, LogicModelParameters params, Timeline timeline) + private static Map convertWires(Set allPins, List wires, Map externalWires, + LogicModelParameters params, Timeline timeline) { Map> connectedPinGroups = getConnectedPinGroups(allPins, wires); - Map logicWiresPerPin = createLogicWires(params, timeline, connectedPinGroups); + Map logicWiresPerPin = createLogicWires(params, timeline, connectedPinGroups, externalWires); setGUIWiresLogicModelBinding(wires, logicWiresPerPin); return logicWiresPerPin; } - private static Map createLogicWires(LogicModelParameters params, Timeline timeline, Map> connectedPinGroups) + private static Map createLogicWires(LogicModelParameters params, Timeline timeline, Map> connectedPinGroups, + Map externalWires) { Map logicWiresPerPin = new HashMap<>(); Map, Wire> logicWiresPerPinGroup = new HashMap<>(); for (Entry> e : connectedPinGroups.entrySet()) - logicWiresPerPin.put(e.getKey(), logicWiresPerPinGroup.computeIfAbsent(e.getValue(), - set -> new Wire(timeline, e.getKey().logicWidth, params.wireTravelTime))); + logicWiresPerPin.put(e.getKey(), logicWiresPerPinGroup.computeIfAbsent(e.getValue(), set -> + { + Wire externalWire = null; + for (Pin p : set) + { + Wire externalWireCandidate = externalWires.get(p); + if (externalWireCandidate != null) + if (externalWire == null) + externalWire = externalWireCandidate; + else if (externalWire.length == externalWireCandidate.length) + Wire.fuse(externalWire, externalWireCandidate); + else + throw new IllegalArgumentException( + "Two pins to external wires with different logicWidths can't be connected directly"); + } + return externalWire == null ? new Wire(timeline, e.getKey().logicWidth, params.wireTravelTime) : externalWire; + })); return logicWiresPerPin; } @@ -137,12 +141,12 @@ public class ViewLogicModelAdapter } @SuppressWarnings("unchecked") - private static Component createAndLinkComponent(Timeline timeline, LogicModelParameters params, + private static void createAndLinkComponent(Timeline timeline, LogicModelParameters params, GUIComponent guiComponent, Map logicWiresPerPin, ComponentAdapter adapter) { if (adapter == null) throw new IllegalArgumentException("Unknown component class: " + guiComponent.getClass()); - return adapter.createAndLinkComponent(timeline, params, (G) guiComponent, logicWiresPerPin); + adapter.createAndLinkComponent(timeline, params, (G) guiComponent, logicWiresPerPin); } private ViewLogicModelAdapter()