Insured InstructionTable removes all Listeners
authorFabian Stemmler <stemmler@in.tum.de>
Sun, 29 Sep 2019 00:14:55 +0000 (02:14 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Sun, 29 Sep 2019 11:44:20 +0000 (13:44 +0200)
plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/SimulationViewEditor.java
plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/nature/MachineContext.java
plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionTable.java
plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionView.java

index d40bc77..cb8e688 100644 (file)
@@ -72,7 +72,7 @@ public class SimulationViewEditor extends EditorPart
 
        public SimulationViewEditor()
        {
-               activeMachineListener = m -> recreateContextDependentControls();
+               activeMachineListener = (oldM, newM) -> recreateContextDependentControls();
                memCellListener = a -> instPreview.refresh();
                clockObserver = o ->
                {
index 1be6b2a..c84e622 100644 (file)
@@ -122,9 +122,10 @@ public class MachineContext
         */
        public final void setActiveMachine(Machine machine)
        {
+               Optional<Machine> oldMachine = activeMachine;
                activeMachine = Optional.ofNullable(machine);
                updateStatus();
-               notifyActiveMachineListeners();
+               notifyActiveMachineListeners(oldMachine, activeMachine);
        }
 
        public final Optional<String> getMachineId()
@@ -208,8 +209,9 @@ public class MachineContext
        {
                if ((status == DEAD || status == CLOSED) && activeMachine.isPresent())
                {
+                       Optional<Machine> oldMachine = activeMachine;
                        activeMachine = Optional.empty();
-                       notifyActiveMachineListeners();
+                       notifyActiveMachineListeners(oldMachine, activeMachine);
                }
        }
 
@@ -247,15 +249,15 @@ public class MachineContext
                }
        }
 
-       private void notifyActiveMachineListeners()
+       private void notifyActiveMachineListeners(Optional<Machine> oldMachine, Optional<Machine> newMachine)
        {
-               machineListeners.forEach(ob -> ob.setMachine(activeMachine));
+               machineListeners.forEach(ob -> ob.setMachine(oldMachine, newMachine));
        }
 
        public void addActiveMachineListener(ActiveMachineListener ob)
        {
                machineListeners.add(ob);
-               ob.setMachine(activeMachine);
+               ob.setMachine(Optional.empty(), activeMachine);
        }
 
        public void removeActiveMachineListener(ActiveMachineListener ob)
@@ -282,7 +284,7 @@ public class MachineContext
        @FunctionalInterface
        public static interface ActiveMachineListener
        {
-               void setMachine(Optional<Machine> machine);
+               void setMachine(Optional<Machine> oldMachine, Optional<Machine> newMachine);
        }
 
        @FunctionalInterface
index 7b17f24..a806bd2 100644 (file)
@@ -51,6 +51,7 @@ public class InstructionTable
                table.setHeaderVisible(true);
                table.setLinesVisible(true);
                viewer.setUseHashlookup(true);
+               table.addDisposeListener(e -> dispose());
 
                TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(viewer, new FocusCellOwnerDrawHighlighter(viewer));
 
@@ -257,7 +258,7 @@ public class InstructionTable
                Display.getDefault().asyncExec(() -> viewer.refresh());
        }
 
-       public void dispose()
+       private void dispose()
        {
                cProv.dispose();
                viewer.getTable().dispose();
index fe03d94..e354c8f 100644 (file)
@@ -24,11 +24,12 @@ import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChan
 import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
 import net.mograsim.machine.mi.MicroInstructionMemoryParser;
 import net.mograsim.plugin.nature.MachineContext;
+import net.mograsim.plugin.nature.MachineContext.ActiveMachineListener;
 import net.mograsim.plugin.nature.ProjectMachineContext;
 import net.mograsim.plugin.tables.DisplaySettings;
 import net.mograsim.plugin.tables.RadixSelector;
 
-public class InstructionView extends EditorPart implements MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
+public class InstructionView extends EditorPart
 {
        private InstructionTableContentProvider provider;
        private boolean dirty = false;
@@ -36,6 +37,33 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
        private InstructionTable table;
        private MachineContext context;
 
+       // Listeners
+       private MemoryCellModifiedListener cellModifiedListener = address ->
+       {
+               setDirty(true);
+               table.refresh();
+       };
+
+       private ActiveMicroInstructionChangedListener activeInstructionChangedListener = address -> highlight(
+                       (int) (address - memory.getDefinition().getMinimalAddress()));
+
+       private MIMemoryReassignedListener reassignedListener = newAssignee ->
+       {
+               // clear highlighting if the memory is reassigned
+               if (newAssignee != memory)
+                       highlight(-1);
+       };
+
+       private ActiveMachineListener activeMachineListener = (oldMachine, newMachine) ->
+       {
+               // clear highlighting if the active machine changes
+               if (newMachine.isEmpty() || !newMachine.equals(oldMachine))
+               {
+                       highlight(-1);
+                       oldMachine.ifPresent(m -> m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener));
+               }
+       };
+
        @SuppressWarnings("unused")
        @Override
        public void createPartControl(Composite parent)
@@ -68,22 +96,8 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
                activationButton.setText("Set Active");
                activationButton.addListener(SWT.Selection, e -> context.getActiveMachine().ifPresent(m ->
                {
-                       // clear highlighting if the memory is reassigned
-                       MIMemoryReassignedListener memReassignedListener = n ->
-                       {
-                               if (n != memory)
-                                       highlight(-1);
-                       };
-                       m.getMicroInstructionMemory().registerMemoryReassignedListener(memReassignedListener);
-                       // clear highlighting if the active machine changes
-                       context.addActiveMachineListener(n ->
-                       {
-                               if (n.isEmpty() || n.get() != m)
-                               {
-                                       highlight(-1);
-                                       m.getMicroInstructionMemory().deregisterMemoryReassignedListener(memReassignedListener);
-                               }
-                       });
+                       m.getMicroInstructionMemory().registerMemoryReassignedListener(reassignedListener);
+                       context.addActiveMachineListener(activeMachineListener);
                        m.getMicroInstructionMemory().bind(memory);
                }));
        }
@@ -92,14 +106,14 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
        {
                if (this.memory != null)
                {
-                       this.memory.deregisterCellModifiedListener(this);
-                       this.memory.deregisterActiveMicroInstructionChangedListener(this);
+                       this.memory.deregisterCellModifiedListener(cellModifiedListener);
+                       this.memory.deregisterActiveMicroInstructionChangedListener(activeInstructionChangedListener);
                }
                this.memory = memory;
                if (memory != null)
                {
-                       this.memory.registerCellModifiedListener(this);
-                       this.memory.registerActiveMicroInstructionChangedListener(this);
+                       this.memory.registerCellModifiedListener(cellModifiedListener);
+                       this.memory.registerActiveMicroInstructionChangedListener(activeInstructionChangedListener);
                }
                if (table != null)
                        table.bindMicroInstructionMemory(memory);
@@ -206,29 +220,19 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
                return false;
        }
 
-       @Override
-       public void update(long address)
-       {
-               setDirty(true);
-               table.refresh();
-       }
-
        private void setDirty(boolean value)
        {
                dirty = value;
                firePropertyChange(PROP_DIRTY);
        }
 
-       @Override
-       public void activeMicroInstructionChanged(long address)
-       {
-               highlight((int) (address - memory.getDefinition().getMinimalAddress()));
-       }
-
        @Override
        public void dispose()
        {
-               table.dispose();
+               memory.deregisterActiveMicroInstructionChangedListener(activeInstructionChangedListener);
+               memory.deregisterCellModifiedListener(cellModifiedListener);
+               context.getActiveMachine().ifPresent(m -> m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener));
+               context.removeActiveMachineListener(activeMachineListener);
                super.dispose();
        }
 }