Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.model.editor / src / net / mograsim / logic / model / editor / handles / HandleManager.java
index e4fb314..0a33509 100644 (file)
@@ -8,15 +8,18 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
 import net.mograsim.logic.model.editor.Editor;
 import net.mograsim.logic.model.editor.states.EditorState;
-import net.mograsim.logic.model.model.ViewModelModifiable;
-import net.mograsim.logic.model.model.components.GUIComponent;
-import net.mograsim.logic.model.model.wires.GUIWire;
+import net.mograsim.logic.model.editor.util.PrioritySet;
+import net.mograsim.logic.model.model.LogicModelModifiable;
+import net.mograsim.logic.model.model.components.ModelComponent;
+import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
+import net.mograsim.logic.model.model.wires.ModelWire;
 import net.mograsim.logic.model.model.wires.MovablePin;
 import net.mograsim.logic.model.model.wires.Pin;
 
@@ -24,19 +27,17 @@ public class HandleManager
 {
        private final Map<Pin, StaticPinHandle> handlePerPin;
        private final Map<Pin, InterfacePinHandle> handlePerInterfacePin;
-       private final Map<GUIWire, List<WirePointHandle>> pointHandlesPerWire;
-       private final Map<GUIWire, WireHandle> handlePerWire;
+       private final Map<ModelWire, List<WirePointHandle>> pointHandlesPerWire;
+       private final Map<ModelWire, WireHandle> handlePerWire;
        private final Set<Handle> handles;
        private final Set<WirePointHandle> wirePointHandles;
-       private final Map<GUIComponent, ComponentHandle> handlePerComp;
+       private final Map<ModelComponent, ComponentHandle> handlePerComp;
 
        private final Collection<Consumer<Handle>> handleAddedListeners;
        private final Collection<Consumer<Handle>> handleRemovedListeners;
        private final Editor editor;
        private boolean initialized = false;
 
-       private CornerHandle cornerHandle;
-
        public HandleManager(Editor editor)
        {
                this.editor = editor;
@@ -44,14 +45,14 @@ public class HandleManager
                handlePerInterfacePin = new HashMap<>();
                pointHandlesPerWire = new HashMap<>();
                handlePerComp = new HashMap<>();
-               handles = new HashSet<>();
+               handles = new PrioritySet<>((a, b) -> Integer.compare(a.getPriority(), b.getPriority()));
                wirePointHandles = new HashSet<>();
                handlePerWire = new HashMap<>();
 
                handleAddedListeners = new ArrayList<>();
                handleRemovedListeners = new ArrayList<>();
 
-               ViewModelModifiable model = editor.getSubmodel();
+               LogicModelModifiable model = editor.getSubmodel();
 
                model.addComponentAddedListener(c -> registerComponent(c));
 
@@ -82,27 +83,27 @@ public class HandleManager
                        System.err.println("Warning! HandleManager was already initialized.");
                else
                {
-                       ViewModelModifiable model = editor.getSubmodel();
-                       Map<String, GUIComponent> compsByName = model.getComponentsByName();
-                       Set<GUIComponent> comps = new HashSet<>(compsByName.values());
-                       GUIComponent interfaceComp = compsByName.get("_submodelinterface");
+                       LogicModelModifiable model = editor.getSubmodel();
+                       Map<String, ModelComponent> compsByName = model.getComponentsByName();
+                       Set<ModelComponent> comps = new HashSet<>(compsByName.values());
+                       ModelComponent interfaceComp = compsByName.get(SubmodelComponent.SUBMODEL_INTERFACE_NAME);
                        comps.remove(interfaceComp);
                        registerInterfaceComponent(interfaceComp);
                        comps.forEach(c -> registerComponent(c));
 
-                       model.getWires().forEach(w -> registerWire(w));
-                       addHandle(cornerHandle = new CornerHandle(editor.toBeEdited));
+                       model.getWiresByName().values().forEach(w -> registerWire(w));
+                       addHandle(new CornerHandle(editor.toBeEdited));
                }
        }
 
-       private void registerInterfaceComponent(GUIComponent c)
+       private void registerInterfaceComponent(ModelComponent c)
        {
                c.getPins().values().forEach(p -> addInterfacePinHandle(p));
                c.addPinAddedListener(p -> addInterfacePinHandle(p));
                c.addPinRemovedListener(p -> removeInterfacePinHandle(p));
        }
 
-       private void registerComponent(GUIComponent c)
+       private void registerComponent(ModelComponent c)
        {
                addComponentHandle(c);
 
@@ -112,10 +113,15 @@ public class HandleManager
                c.addPinRemovedListener(p -> removePinHandle(p));
        }
 
-       private void registerWire(GUIWire wire)
+       private void registerWire(ModelWire wire)
        {
-               wire.addPathChangedListener((w, diff) ->
+               Point[] path = wire.getPath();
+               AtomicInteger oldLength = new AtomicInteger(path == null ? 0 : path.length);
+               wire.addPathChangedListener(w ->
                {
+                       Point[] newPath = w.getPath();
+                       int newLength = newPath == null ? 0 : newPath.length;
+                       int diff = newLength - oldLength.getAndSet(newLength);
                        if (diff != 0)
                        {
                                if (diff > 0)
@@ -134,9 +140,9 @@ public class HandleManager
                        pointHandlesPerWire.get(w).forEach(h -> h.updatePos());
                });
                addWireHandle(wire);
-               if (wire.getPath() == null)
+               if (path == null)
                        return;
-               for (int i = 0; i < wire.getPath().length; i++)
+               for (int i = 0; i < path.length; i++)
                {
                        addWirePointHandle(wire);
                }
@@ -146,14 +152,14 @@ public class HandleManager
        // -- Adding/Removing handles -- ///
        ///////////////////////////////////
 
-       private void addComponentHandle(GUIComponent c)
+       private void addComponentHandle(ModelComponent c)
        {
-               ComponentHandle h = new ComponentHandle(c);
+               ComponentHandle h = new ComponentHandle(editor.getSubmodel(), c);
                handlePerComp.put(c, h);
                addHandle(h);
        }
 
-       private void removeComponentHandle(GUIComponent c)
+       private void removeComponentHandle(ModelComponent c)
        {
                ComponentHandle h = handlePerComp.get(c);
                handlePerComp.remove(c);
@@ -191,7 +197,7 @@ public class HandleManager
                removeHandle(h);
        }
 
-       private void addWirePointHandle(GUIWire w)
+       private void addWirePointHandle(ModelWire w)
        {
                List<WirePointHandle> wireHandles = pointHandlesPerWire.get(w);
                WirePointHandle h;
@@ -208,16 +214,19 @@ public class HandleManager
                addHandle(h);
        }
 
-       void destroyWirePointHandle(GUIWire owner, WirePointHandle h)
+       void destroyWirePointHandle(ModelWire owner, WirePointHandle h)
        {
-               List<WirePointHandle> handles = pointHandlesPerWire.get(owner);
-               int pointIndex = handles.indexOf(h);
-               handles.remove(pointIndex);
-               removeHandle(h);
-               owner.removePathPoint(pointIndex);
+               if (pointHandlesPerWire.containsKey(owner))
+               {
+                       List<WirePointHandle> handles = pointHandlesPerWire.get(owner);
+                       int pointIndex = handles.indexOf(h);
+                       handles.remove(pointIndex);
+                       removeHandle(h);
+                       owner.removePathPoint(pointIndex);
+               }
        }
 
-       private void removeWirePointHandles(GUIWire owner)
+       private void removeWirePointHandles(ModelWire owner)
        {
                if (!pointHandlesPerWire.containsKey(owner))
                        return;
@@ -229,14 +238,14 @@ public class HandleManager
                pointHandlesPerWire.remove(owner);
        }
 
-       private void addWireHandle(GUIWire w)
+       private void addWireHandle(ModelWire w)
        {
-               WireHandle h = new WireHandle(w);
+               WireHandle h = new WireHandle(editor.getSubmodel(), w);
                handlePerWire.put(w, h);
                addHandle(h);
        }
 
-       private void removeWireHandle(GUIWire w)
+       private void removeWireHandle(ModelWire w)
        {
                WireHandle h = handlePerWire.get(w);
                handlePerWire.remove(w);
@@ -261,12 +270,12 @@ public class HandleManager
                return handlePerPin.get(parent);
        }
 
-       public ComponentHandle getHandle(GUIComponent parent)
+       public ComponentHandle getHandle(ModelComponent parent)
        {
                return handlePerComp.get(parent);
        }
 
-       public WireHandle getHandle(GUIWire parent)
+       public WireHandle getHandle(ModelWire parent)
        {
                return handlePerWire.get(parent);
        }
@@ -279,7 +288,7 @@ public class HandleManager
        /**
         * @return A Collection of the registered {@link WirePointHandle}s of the specified wire
         */
-       public Collection<WirePointHandle> getWirePointHandles(GUIWire parent)
+       public Collection<WirePointHandle> getWirePointHandles(ModelWire parent)
        {
                return pointHandlesPerWire.get(parent).stream().collect(Collectors.toSet());
        }
@@ -335,18 +344,13 @@ public class HandleManager
        public void click(Point clicked, int stateMask)
        {
                EditorState entryState = editor.stateManager.getState();
-
-               if (!cornerHandle.click(clicked.x, clicked.y, stateMask, entryState))
-                       if (!click(handlePerPin.values(), clicked, entryState, stateMask))
-                               if (!click(handlePerInterfacePin.values(), clicked, entryState, stateMask))
-                                       if (!click(getWirePointHandles(), clicked, entryState, stateMask))
-                                               if (!click(getWireHandles(), clicked, entryState, stateMask))
-                                                       if (!click(handlePerComp.values(), clicked, entryState, stateMask))
-                                                               entryState.clickedEmpty(clicked, stateMask);
+               // TODO: As soon as wires connected to a component being removed also are removed, change priority)
+               if (!click(handles, clicked, entryState, stateMask))
+                       entryState.clickedEmpty(clicked, stateMask);
                entryState.clicked(clicked, stateMask);
        }
 
-       private boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
+       private static boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
        {
                for (Handle h : handles)
                        if (h.click(clicked.x, clicked.y, stateMask, state))