Highlighting Instructions is now based on the selected DebugTarget
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / tables / mi / InstructionView.java
index b50dc84..12f3139 100644 (file)
@@ -2,39 +2,84 @@ package net.mograsim.plugin.tables.mi;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Optional;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.swt.SWT;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.contexts.IDebugContextManager;
+import org.eclipse.debug.ui.contexts.IDebugContextService;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.part.EditorPart;
 
+import net.mograsim.machine.Machine;
+import net.mograsim.machine.Machine.ActiveMicroInstructionChangedListener;
 import net.mograsim.machine.Memory.MemoryCellModifiedListener;
 import net.mograsim.machine.mi.MicroInstructionMemory;
-import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener;
 import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
 import net.mograsim.machine.mi.MicroInstructionMemoryParser;
-import net.mograsim.plugin.MachineContext;
+import net.mograsim.plugin.launch.MachineDebugContextListener;
+import net.mograsim.plugin.launch.MachineDebugTarget;
+import net.mograsim.plugin.launch.MachineLaunchConfigType.MachineLaunchParams;
+import net.mograsim.plugin.nature.MachineContext;
+import net.mograsim.plugin.nature.ProjectMachineContext;
 import net.mograsim.plugin.tables.DisplaySettings;
-import net.mograsim.plugin.tables.LazyTableViewer;
 import net.mograsim.plugin.tables.RadixSelector;
 
-public class InstructionView extends EditorPart implements MemoryCellModifiedListener, ActiveMicroInstructionChangedListener
+public class InstructionView extends EditorPart
 {
        private InstructionTableContentProvider provider;
-       private int highlighted = 0;
        private boolean dirty = false;
        private MicroInstructionMemory memory;
        private InstructionTable table;
+       private MachineContext context;
+
+       private IFile file;
+
+       // Listeners
+       private MemoryCellModifiedListener cellModifiedListener = address ->
+       {
+               setDirty(true);
+               table.refresh();
+       };
+
+       private ActiveMicroInstructionChangedListener instChangeListener = (oldAddress, newAddress) ->
+       {
+               highlight((int) (newAddress - memory.getDefinition().getMinimalAddress()));
+       };
+
+       private MachineDebugContextListener debugContextListener = new MachineDebugContextListener()
+       {
+               @Override
+               public void machineDebugContextChanged(Optional<MachineDebugTarget> oldTarget, Optional<MachineDebugTarget> newTarget)
+               {
+                       instChangeListener.instructionChanged(-1, -1);
+                       oldTarget.ifPresent(target -> target.getMachine().removeActiveMicroInstructionChangedListener(instChangeListener));
+
+                       newTarget.ifPresent(target ->
+                       {
+                               MachineLaunchParams params = target.getLaunchParams();
+                               IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(params.getProjectPath());
+
+                               if (file.equals(project.getFile(params.getMpmPath())))
+                               {
+                                       Machine m = target.getMachine();
+                                       target.getMachine().addActiveMicroInstructionChangedListener(instChangeListener);
+                                       instChangeListener.instructionChanged(-1, m.getActiveMicroInstructionAddress());
+                               }
+                       });
+               }
+       };
 
        @SuppressWarnings("unused")
        @Override
@@ -47,77 +92,60 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
                DisplaySettings displaySettings = new DisplaySettings();
                new RadixSelector(parent, displaySettings);
 
-               addActivationButton(parent);
-
-               table = new InstructionTable(parent, displaySettings);
+               table = new InstructionTable(parent, displaySettings, getSite().getWorkbenchWindow().getWorkbench().getThemeManager());
                table.setContentProvider(provider);
                table.bindMicroInstructionMemory(memory);
 
                GridData viewerData = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
                viewerData.horizontalSpan = 3;
                table.getTableViewer().getTable().setLayoutData(viewerData);
-       }
 
-       public void highlight(int index)
-       {
-               Display.getDefault().asyncExec(() ->
-               {
-                       LazyTableViewer viewer = table.getTableViewer();
-                       viewer.highlightRow(highlighted, false);
-                       highlighted = index;
-                       viewer.highlightRow(index, true);
-                       viewer.getTable().setTopIndex(index);
-               });
+               IDebugContextManager debugCManager = DebugUITools.getDebugContextManager();
+               IDebugContextService contextService = debugCManager.getContextService(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+               contextService.addDebugContextListener(debugContextListener);
+               debugContextListener.debugContextChanged(contextService.getActiveContext());
+               parent.addDisposeListener(e -> contextService.removeDebugContextListener(debugContextListener));
        }
 
-       private void addActivationButton(Composite parent)
+       public void highlight(int row)
        {
-               Button activationButton = new Button(parent, SWT.PUSH);
-               activationButton.setText("Set Active");
-               activationButton.addListener(SWT.Selection,
-                               e -> MachineContext.getInstance().getMachine().getMicroInstructionMemory().bind(memory));
+               table.highlight(row);
        }
 
        public void bindMicroInstructionMemory(MicroInstructionMemory memory)
        {
+               if (this.memory != null)
+               {
+                       this.memory.deregisterCellModifiedListener(cellModifiedListener);
+               }
                this.memory = memory;
                if (memory != null)
                {
-                       this.memory.registerCellModifiedListener(this);
-                       this.memory.registerActiveMicroInstructionChangedListener(this);
+                       this.memory.registerCellModifiedListener(cellModifiedListener);
                }
                if (table != null)
                        table.bindMicroInstructionMemory(memory);
        }
 
-       private void open(IFile file)
+       private void open(IFile file) throws IOException, MicroInstructionMemoryParseException, CoreException
        {
-               try
-               {
-                       bindMicroInstructionMemory(MicroInstructionMemoryParser.parseMemory(
-                                       MachineContext.getInstance().getMachine().getDefinition().getMicroInstructionMemoryDefinition(), file.getContents()));
-               }
-               catch (IOException | MicroInstructionMemoryParseException | CoreException e)
-               {
-                       e.printStackTrace();
-               }
+               bindMicroInstructionMemory(MicroInstructionMemoryParser.parseMemory(
+                               context.getMachineDefinition().orElseThrow(() -> new MicroInstructionMemoryParseException("No MachineDefinition assigned!"))
+                                               .getMicroInstructionMemoryDefinition(),
+                               file.getContents()));
        }
 
-       private void save(IFile file, IProgressMonitor progressMonitor)
+       private void save(IFile file, IProgressMonitor progressMonitor) throws IOException, CoreException, MicroInstructionMemoryParseException
        {
                if (memory == null)
                {
-                       System.err.println("Failed to write MicroprogrammingMemory to File. No MicroprogrammingMemory assigned.");
-                       return;
+                       throw new MicroInstructionMemoryParseException(
+                                       "Failed to write MicroprogrammingMemory to File. No MicroprogrammingMemory assigned.");
                }
                try (InputStream toWrite = MicroInstructionMemoryParser.write(memory))
                {
                        file.setContents(toWrite, 0, progressMonitor);
                }
-               catch (IOException | CoreException e)
-               {
-                       e.printStackTrace();
-               }
        }
 
        @Override
@@ -133,9 +161,18 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
                if (input instanceof IFileEditorInput)
                {
                        IFileEditorInput pathInput = (IFileEditorInput) input;
-                       save(pathInput.getFile(), progressMonitor);
-                       setDirty(false);
-               }
+                       try
+                       {
+                               save(pathInput.getFile(), progressMonitor);
+                               setDirty(false);
+                       }
+                       catch (Exception e)
+                       {
+                               e.printStackTrace();
+                               progressMonitor.setCanceled(true);
+                       }
+               } else
+                       progressMonitor.setCanceled(true);
        }
 
        @Override
@@ -161,13 +198,23 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
        {
                setSite(site);
                setInput(input);
-               if (input instanceof IFileEditorInput)
+               try
                {
-                       IFileEditorInput fileInput = (IFileEditorInput) input;
-                       setPartName(fileInput.getName());
-                       open(fileInput.getFile());
+                       if (input instanceof IFileEditorInput)
+                       {
+                               IFileEditorInput fileInput = (IFileEditorInput) input;
+                               file = fileInput.getFile();
+                               context = ProjectMachineContext.getMachineContextOf(file.getProject());
+
+                               setPartName(fileInput.getName());
+                               open(file);
+                       } else
+                               throw new IllegalArgumentException("Expected IFileEditorInput!");
+               }
+               catch (Exception e)
+               {
+                       throw new PartInitException("Failed to read input!", e);
                }
-
        }
 
        @Override
@@ -182,13 +229,6 @@ 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;
@@ -196,8 +236,9 @@ public class InstructionView extends EditorPart implements MemoryCellModifiedLis
        }
 
        @Override
-       public void activeMicroInstructionChanged(long address)
+       public void dispose()
        {
-               highlight((int) (address - memory.getDefinition().getMinimalAddress()));
+               memory.deregisterCellModifiedListener(cellModifiedListener);
+               super.dispose();
        }
 }