Made MPM configurable; changed startup exec speed from 10 to 1
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineLaunchConfigType.java
1 package net.mograsim.plugin.launch;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.Optional;
6
7 import org.eclipse.core.resources.IFile;
8 import org.eclipse.core.resources.IProject;
9 import org.eclipse.core.resources.IResourceChangeEvent;
10 import org.eclipse.core.resources.IResourceChangeListener;
11 import org.eclipse.core.resources.ResourcesPlugin;
12 import org.eclipse.core.runtime.CoreException;
13 import org.eclipse.core.runtime.IProgressMonitor;
14 import org.eclipse.core.runtime.IStatus;
15 import org.eclipse.core.runtime.Status;
16 import org.eclipse.debug.core.ILaunch;
17 import org.eclipse.debug.core.ILaunchConfiguration;
18 import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
19 import org.eclipse.ui.statushandlers.StatusManager;
20
21 import net.mograsim.machine.Machine;
22 import net.mograsim.machine.MachineDefinition;
23 import net.mograsim.machine.mi.MicroInstructionMemory;
24 import net.mograsim.machine.mi.MicroInstructionMemoryDefinition;
25 import net.mograsim.machine.mi.MicroInstructionMemoryParser;
26 import net.mograsim.plugin.MograsimActivator;
27 import net.mograsim.plugin.nature.MachineContext;
28 import net.mograsim.plugin.nature.MograsimNature;
29 import net.mograsim.plugin.nature.ProjectMachineContext;
30
31 public class MachineLaunchConfigType extends LaunchConfigurationDelegate
32 {
33         public static final String PROJECT_ATTR = MograsimActivator.PLUGIN_ID + "project";
34         public static final String MPM_FILE_ATTR = MograsimActivator.PLUGIN_ID + "mpm";
35
36         private final IResourceChangeListener resChangedListener;
37
38         public MachineLaunchConfigType()
39         {
40                 this.resChangedListener = this::resourceChanged;
41                 ResourcesPlugin.getWorkspace().addResourceChangeListener(resChangedListener,
42                                 // IResourceChangeEvent.POST_BUILD |
43                                 IResourceChangeEvent.POST_CHANGE |
44                                 // IResourceChangeEvent.PRE_BUILD |
45                                 // IResourceChangeEvent.PRE_CLOSE |
46                                 // IResourceChangeEvent.PRE_DELETE |
47                                 // IResourceChangeEvent.PRE_REFRESH |
48                                                 0);
49         }
50
51         @Override
52         public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException
53         {
54                 String projName = configuration.getAttribute(PROJECT_ATTR, "");
55                 if ("".equals(projName))
56                         return showErrorAndReturnFalse("No project specified");
57
58                 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
59                 if (!project.isAccessible())
60                         return showErrorAndReturnFalse("Project not accessible");
61                 if (!project.hasNature(MograsimNature.NATURE_ID))
62                         return showErrorAndReturnFalse("Project is not a Mograsim project");
63
64                 MachineContext machineContext = ProjectMachineContext.getMachineContextOf(project);
65                 Optional<MachineDefinition> machDefOptional = machineContext.getMachineDefinition();
66                 if (machDefOptional.isEmpty())
67                         return showErrorAndReturnFalse("No machine definition set");
68
69                 MachineDefinition machineDefinition = machDefOptional.orElseThrow();
70                 MicroInstructionMemoryDefinition miMemDef = machineDefinition.getMicroInstructionMemoryDefinition();
71
72                 String mpmFileName = configuration.getAttribute(MPM_FILE_ATTR, "");
73                 if ("".equals(mpmFileName))
74                         return showErrorAndReturnFalse("No MPM file specified");
75
76                 IFile mpmFile = project.getFile(mpmFileName);
77                 if (!mpmFile.isAccessible())
78                         return showErrorAndReturnFalse("MPM file not accessible");
79
80                 try (InputStream mpmStream = mpmFile.getContents())
81                 {
82                         MicroInstructionMemoryParser.parseMemory(miMemDef, mpmStream);
83                 }
84                 catch (IOException e)
85                 {
86                         throw new CoreException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Unexpected IO exception reading MPM file", e));
87                 }
88
89                 return super.preLaunchCheck(configuration, mode, monitor);
90         }
91
92         private static boolean showErrorAndReturnFalse(String message)
93         {
94                 StatusManager.getManager().handle(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, message, null), StatusManager.SHOW);
95                 return false;
96         }
97
98         @Override
99         public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException
100         {
101                 String projName = configuration.getAttribute(PROJECT_ATTR, "");
102                 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
103
104                 MachineContext machineContext = ProjectMachineContext.getMachineContextOf(project);
105                 MachineDefinition machineDefinition = machineContext.getMachineDefinition().orElseThrow();
106                 MicroInstructionMemoryDefinition miMemDef = machineDefinition.getMicroInstructionMemoryDefinition();
107
108                 IFile mpmFile = project.getFile(configuration.getAttribute(MPM_FILE_ATTR, ""));
109
110                 MicroInstructionMemory mpm;
111                 try (InputStream mpmStream = mpmFile.getContents())
112                 {
113                         mpm = MicroInstructionMemoryParser.parseMemory(miMemDef, mpmStream);
114                 }
115                 catch (IOException e)
116                 {
117                         throw new CoreException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, "Unexpected IO exception reading MPM file", e));
118                 }
119
120                 MachineDebugTarget debugTarget = new MachineDebugTarget(new MachineProcess(launch, machineDefinition));
121                 debugTarget.setExecutionSpeed(1);
122                 Machine machine = debugTarget.getMachine();
123                 machine.getMicroInstructionMemory().bind(mpm);
124                 machine.reset();
125         }
126
127         private void resourceChanged(IResourceChangeEvent event)
128         {
129                 // TODO react to MPM changes
130                 int type = event.getType();
131                 String typeStr;
132                 switch (type)
133                 {
134                 case IResourceChangeEvent.POST_BUILD:
135                         typeStr = "POST_BUILD";
136                         break;
137                 case IResourceChangeEvent.POST_CHANGE:
138                         typeStr = "POST_CHANGE";
139                         break;
140                 case IResourceChangeEvent.PRE_BUILD:
141                         typeStr = "PRE_BUILD";
142                         break;
143                 case IResourceChangeEvent.PRE_CLOSE:
144                         typeStr = "PRE_CLOSE";
145                         break;
146                 case IResourceChangeEvent.PRE_DELETE:
147                         typeStr = "PRE_DELETE";
148                         break;
149                 case IResourceChangeEvent.PRE_REFRESH:
150                         typeStr = "PRE_REFRESH";
151                         break;
152                 default:
153                         typeStr = "<unknown: " + type + ">";
154                 }
155                 System.out.println(typeStr + ": " + event);
156         }
157 }