From da1a7df25582ae1fe277762c2ba5640d4697a71c Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Sun, 29 Sep 2019 22:51:48 +0200 Subject: [PATCH] Made MPM configurable; changed startup exec speed from 10 to 1 --- .../launch/MachineLaunchConfigType.java | 80 ++++++++++- .../launch/MainMachineLaunchConfigTab.java | 124 +++++++++++++----- .../util/FileExtensionViewerFilter.java | 30 +++++ 3 files changed, 197 insertions(+), 37 deletions(-) create mode 100644 plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/FileExtensionViewerFilter.java diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineLaunchConfigType.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineLaunchConfigType.java index 27aca7e1..32ea8325 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineLaunchConfigType.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MachineLaunchConfigType.java @@ -1,23 +1,37 @@ package net.mograsim.plugin.launch; +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.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.LaunchConfigurationDelegate; +import org.eclipse.ui.statushandlers.StatusManager; +import net.mograsim.machine.Machine; import net.mograsim.machine.MachineDefinition; +import net.mograsim.machine.mi.MicroInstructionMemory; +import net.mograsim.machine.mi.MicroInstructionMemoryDefinition; +import net.mograsim.machine.mi.MicroInstructionMemoryParser; import net.mograsim.plugin.MograsimActivator; import net.mograsim.plugin.nature.MachineContext; +import net.mograsim.plugin.nature.MograsimNature; import net.mograsim.plugin.nature.ProjectMachineContext; public class MachineLaunchConfigType extends LaunchConfigurationDelegate { public static final String PROJECT_ATTR = MograsimActivator.PLUGIN_ID + "project"; + public static final String MPM_FILE_ATTR = MograsimActivator.PLUGIN_ID + "mpm"; private final IResourceChangeListener resChangedListener; @@ -34,16 +48,80 @@ public class MachineLaunchConfigType extends LaunchConfigurationDelegate 0); } + @Override + public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException + { + String projName = configuration.getAttribute(PROJECT_ATTR, ""); + if ("".equals(projName)) + return showErrorAndReturnFalse("No project specified"); + + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName); + if (!project.isAccessible()) + return showErrorAndReturnFalse("Project not accessible"); + if (!project.hasNature(MograsimNature.NATURE_ID)) + return showErrorAndReturnFalse("Project is not a Mograsim project"); + + MachineContext machineContext = ProjectMachineContext.getMachineContextOf(project); + Optional machDefOptional = machineContext.getMachineDefinition(); + if (machDefOptional.isEmpty()) + return showErrorAndReturnFalse("No machine definition set"); + + MachineDefinition machineDefinition = machDefOptional.orElseThrow(); + MicroInstructionMemoryDefinition miMemDef = machineDefinition.getMicroInstructionMemoryDefinition(); + + String mpmFileName = configuration.getAttribute(MPM_FILE_ATTR, ""); + if ("".equals(mpmFileName)) + return showErrorAndReturnFalse("No MPM file specified"); + + IFile mpmFile = project.getFile(mpmFileName); + if (!mpmFile.isAccessible()) + return showErrorAndReturnFalse("MPM file not accessible"); + + try (InputStream mpmStream = mpmFile.getContents()) + { + MicroInstructionMemoryParser.parseMemory(miMemDef, mpmStream); + } + catch (IOException e) + { + throw new CoreException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Unexpected IO exception reading MPM file", e)); + } + + return super.preLaunchCheck(configuration, mode, monitor); + } + + private static boolean showErrorAndReturnFalse(String message) + { + StatusManager.getManager().handle(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, message, null), StatusManager.SHOW); + return false; + } + @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { String projName = configuration.getAttribute(PROJECT_ATTR, ""); IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName); + MachineContext machineContext = ProjectMachineContext.getMachineContextOf(project); MachineDefinition machineDefinition = machineContext.getMachineDefinition().orElseThrow(); + MicroInstructionMemoryDefinition miMemDef = machineDefinition.getMicroInstructionMemoryDefinition(); + + IFile mpmFile = project.getFile(configuration.getAttribute(MPM_FILE_ATTR, "")); + + MicroInstructionMemory mpm; + try (InputStream mpmStream = mpmFile.getContents()) + { + mpm = MicroInstructionMemoryParser.parseMemory(miMemDef, mpmStream); + } + catch (IOException e) + { + throw new CoreException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Unexpected IO exception reading MPM file", e)); + } MachineDebugTarget debugTarget = new MachineDebugTarget(new MachineProcess(launch, machineDefinition)); - debugTarget.setExecutionSpeed(10d); + debugTarget.setExecutionSpeed(1); + Machine machine = debugTarget.getMachine(); + machine.getMicroInstructionMemory().bind(mpm); + machine.reset(); } private void resourceChanged(IResourceChangeEvent event) diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MainMachineLaunchConfigTab.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MainMachineLaunchConfigTab.java index 6579efc9..68baf2f7 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MainMachineLaunchConfigTab.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/launch/MainMachineLaunchConfigTab.java @@ -3,6 +3,7 @@ package net.mograsim.plugin.launch; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.function.Supplier; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -29,15 +30,19 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; +import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import net.mograsim.plugin.nature.MograsimNature; +import net.mograsim.plugin.util.FileExtensionViewerFilter; import net.mograsim.plugin.util.ImageDescriptorWithMargins; //a big part of this class is stolen from org.eclipse.jdt.debug.ui public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab { private Text projSelText; + private Text mpmFileSelText; @Override public void createControl(Composite parent) @@ -48,11 +53,20 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab innerParent.setLayout(new GridLayout()); + this.projSelText = createResourceSelectorGroup(innerParent, this::chooseMograsimProject); + + this.mpmFileSelText = createResourceSelectorGroup(innerParent, this::chooseMPMFile); + + // TODO RAM selector + } + + private Text createResourceSelectorGroup(Composite innerParent, Supplier chooser) + { Group projSelGroup = new Group(innerParent, SWT.NONE); projSelGroup.setLayout(new GridLayout(2, false)); projSelGroup.setText("&Project:"); projSelGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - projSelText = new Text(projSelGroup, SWT.BORDER); + Text projSelText = new Text(projSelGroup, SWT.BORDER); projSelText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); projSelText.addModifyListener(e -> updateLaunchConfigurationDialog()); Button projSelButton = new Button(projSelGroup, SWT.PUSH); @@ -63,12 +77,11 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab projSelButton.setText("&Browse..."); projSelButton.addListener(SWT.Selection, e -> { - IProject choosedProject = chooseMograsimProject(); - if (choosedProject != null) - projSelText.setText(choosedProject.getName()); + String chosen = chooser.get(); + if (chosen != null) + projSelText.setText(chosen); }); - - // TODO MPM / RAM selectors + return projSelText; } private static int calculateWidthHint(Control c) @@ -77,7 +90,7 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab return Math.max(wHint, c.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); } - private IProject chooseMograsimProject() + private String chooseMograsimProject() { WorkbenchLabelProvider renderer = new WorkbenchLabelProvider() { @@ -88,11 +101,39 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab } }; ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), renderer); - dialog.setTitle("title"); - dialog.setMessage("message"); + dialog.setTitle("Project Selection"); + dialog.setMessage("Select a Mograsim project"); dialog.setElements(filterOpenMograsimProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects())); if (dialog.open() == Window.OK) - return (IProject) dialog.getFirstResult(); + return ((IProject) dialog.getFirstResult()).getName(); + return null; + } + + private String chooseMPMFile() + { + WorkbenchLabelProvider renderer = new WorkbenchLabelProvider() + { + @Override + protected ImageDescriptor decorateImage(ImageDescriptor input, Object element) + { + return new ImageDescriptorWithMargins(input, new Point(22, 16)); + } + }; + ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), renderer, new WorkbenchContentProvider()); + dialog.setInput(getSelectedProject()); + dialog.addFilter(new FileExtensionViewerFilter("mpm")); + + if (dialog.open() == Window.OK) + return ((IResource) dialog.getResult()[0]).getProjectRelativePath().toPortableString(); + return null; + } + + private IProject getSelectedProject() + { + String projName = projSelText.getText().trim(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if (workspace.validateName(projName, IResource.PROJECT).isOK()) + return workspace.getRoot().getProject(projName); return null; } @@ -135,16 +176,24 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { - Set associatedResources = new HashSet<>(); String projName = projSelText.getText().trim(); - if (projName.length() != 0) + String mpmFileName = mpmFileSelText.getText().trim(); + + Set associatedResources = new HashSet<>(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if (workspace.validateName(projName, IResource.PROJECT).isOK()) { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject project = workspace.getRoot().getProject(projName); try { if (project != null && project.isAccessible() && project.hasNature(MograsimNature.NATURE_ID)) - associatedResources.add(project); + { + IResource mpmFile = project.findMember(mpmFileName); + if (mpmFile != null && mpmFile.exists() && mpmFile.getType() == IResource.FILE) + associatedResources.add(mpmFile); + else + associatedResources.add(project); + } } catch (CoreException e) { @@ -153,6 +202,7 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab } configuration.setMappedResources(associatedResources.toArray(IResource[]::new)); configuration.setAttribute(MachineLaunchConfigType.PROJECT_ATTR, projName); + configuration.setAttribute(MachineLaunchConfigType.MPM_FILE_ATTR, mpmFileName); } @Override @@ -162,44 +212,46 @@ public class MainMachineLaunchConfigTab extends AbstractLaunchConfigurationTab setMessage(null); String projName = projSelText.getText().trim(); if (projName.length() == 0) - { - setErrorMessage("No project specified"); - return false; - } + return setErrorAndReturnFalse("No project specified"); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); IStatus status = workspace.validateName(projName, IResource.PROJECT); if (!status.isOK()) - { - setErrorMessage(NLS.bind("Illegal project name: {0}", new String[] { status.getMessage() })); - return false; - } + return setErrorAndReturnFalse("Illegal project name: {0}: {1}", projName, status.getMessage()); + IProject project = workspace.getRoot().getProject(projName); if (!project.exists()) - { - setErrorMessage(NLS.bind("Project {0} does not exist", new String[] { projName })); - return false; - } + return setErrorAndReturnFalse("Project {0} does not exist", projName); if (!project.isOpen()) - { - setErrorMessage(NLS.bind("Project {0} is closed", new String[] { projName })); - return false; - } + return setErrorAndReturnFalse("Project {0} is closed", projName); try { if (!project.hasNature(MograsimNature.NATURE_ID)) - { - setErrorMessage(NLS.bind("Project {0} is not a Mograsim project", new String[] { projName })); - return false; - } + return setErrorAndReturnFalse("Project {0} is not a Mograsim project", projName); } catch (CoreException e) { - setErrorMessage(e.getStatus().getMessage()); - return false; + return setErrorAndReturnFalse(e.getStatus().getMessage()); } + + String mpmFileName = mpmFileSelText.getText().trim(); + if (mpmFileName.length() == 0) + return setErrorAndReturnFalse("No MPM file specified"); + IResource mpmResource = project.findMember(mpmFileName); + if (mpmResource == null || !mpmResource.exists()) + return setErrorAndReturnFalse("MPM file {0} does not exist", mpmFileName); + if (mpmResource.getType() != IResource.FILE) + return setErrorAndReturnFalse("MPM file {0} is not a file", mpmFileName); + return true; } + private boolean setErrorAndReturnFalse(String message, String... params) + { + setErrorMessage(NLS.bind(message, params)); + return false; + } + @Override public String getName() { diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/FileExtensionViewerFilter.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/FileExtensionViewerFilter.java new file mode 100644 index 00000000..a7029372 --- /dev/null +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/FileExtensionViewerFilter.java @@ -0,0 +1,30 @@ +package net.mograsim.plugin.util; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +public class FileExtensionViewerFilter extends ViewerFilter +{ + private final String fileext; + + public FileExtensionViewerFilter(String fileext) + { + this.fileext = fileext; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) + { + IResource elementResource = (IResource) element; + switch (elementResource.getType()) + { + case IResource.FILE: + return elementResource.getProjectRelativePath().getFileExtension().equals(fileext); + case IResource.FOLDER: + return true; + default: + return true; + } + } +} \ No newline at end of file -- 2.17.1