1 package net.mograsim.plugin.launch;
3 import java.util.Arrays;
5 import org.eclipse.core.resources.IMarkerDelta;
6 import org.eclipse.core.runtime.IStatus;
7 import org.eclipse.core.runtime.PlatformObject;
8 import org.eclipse.core.runtime.Status;
9 import org.eclipse.debug.core.DebugEvent;
10 import org.eclipse.debug.core.DebugException;
11 import org.eclipse.debug.core.DebugPlugin;
12 import org.eclipse.debug.core.ILaunch;
13 import org.eclipse.debug.core.ILaunchConfiguration;
14 import org.eclipse.debug.core.model.IBreakpoint;
15 import org.eclipse.debug.core.model.IDebugElement;
16 import org.eclipse.debug.core.model.IDebugTarget;
17 import org.eclipse.debug.core.model.IMemoryBlock;
18 import org.eclipse.debug.core.model.IMemoryBlockExtension;
19 import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
20 import org.eclipse.debug.core.model.IProcess;
21 import org.eclipse.debug.core.model.IStepFilters;
22 import org.eclipse.debug.core.model.IThread;
24 import net.mograsim.machine.Machine;
25 import net.mograsim.plugin.MograsimActivator;
27 public class MachineDebugTarget extends PlatformObject implements IDebugTarget, IMemoryBlockRetrievalExtension
29 private final MachineProcess process;
31 public MachineDebugTarget(MachineProcess process)
33 this.process = process;
35 DebugPlugin.getDefault().addDebugEventListener(es -> Arrays.stream(es).filter(e -> e.getSource() == process).forEach(e ->
39 case DebugEvent.RESUME:
40 fireResumeEvent(e.getDetail());
42 case DebugEvent.SUSPEND:
43 fireSuspendEvent(e.getDetail());
45 case DebugEvent.TERMINATE:
53 getLaunch().addDebugTarget(this);
57 public Machine getMachine()
59 return process.getMachine();
63 public String getName() throws DebugException
65 return process.getName();
69 public String getModelIdentifier()
71 return MograsimActivator.PLUGIN_ID;
75 public IDebugTarget getDebugTarget()
81 public ILaunch getLaunch()
83 return process.getLaunch();
86 public void setExecutionSpeed(double speed)
88 process.setExecutionSpeed(speed);
92 public boolean isSuspended()
94 return process.isSuspended();
98 public boolean canSuspend()
100 return process.canSuspend();
104 public void suspend() throws DebugException
110 public boolean canResume()
112 return process.canResume();
116 public void resume() throws DebugException
122 public boolean isTerminated()
124 return process.isTerminated();
128 public boolean canTerminate()
130 return process.canTerminate();
134 public void terminate() throws DebugException
140 public boolean supportsBreakpoint(IBreakpoint breakpoint)
146 public void breakpointAdded(IBreakpoint breakpoint)
148 // ignore; we don't support breakpoints
152 public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta)
154 // ignore; we don't support breakpoints
158 public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta)
160 // ignore; we don't support breakpoints
164 public boolean isDisconnected()
170 public boolean canDisconnect()
176 public void disconnect() throws DebugException
178 throw new DebugException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.NOT_SUPPORTED,
179 "Can't disconnect from a MachineDebugTarget", null));
183 public boolean supportsStorageRetrieval()
188 @SuppressWarnings("deprecation") // TODO can we throw a DebugException instead?
190 public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException
192 return new MainMemoryBlock(this, startAddress, length);
196 public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException
198 return new MainMemoryBlockExtension(this, expression, context);
202 public MachineProcess getProcess()
208 public boolean hasThreads() throws DebugException
214 public IThread[] getThreads() throws DebugException
216 return new IThread[0];
219 @SuppressWarnings("unchecked")
221 public <T> T getAdapter(Class<T> adapter)
223 if (adapter == IDebugElement.class)
226 // leave this here; maybe we implement IStepFilters someday
227 if (adapter == IStepFilters.class)
228 if (this instanceof IStepFilters)
229 return (T) getDebugTarget();
231 if (adapter == IDebugTarget.class)
232 return (T) getDebugTarget();
234 if (adapter == ILaunch.class)
235 return (T) getLaunch();
237 if (adapter == IProcess.class)
238 return (T) getProcess();
241 if (adapter == ILaunchConfiguration.class)
242 return (T) getLaunch().getLaunchConfiguration();
244 return super.getAdapter(adapter);
248 * Fires a creation event for this debug element.
250 private void fireCreationEvent()
252 fireEvent(new DebugEvent(this, DebugEvent.CREATE));
256 * Fires a resume for this debug element with the specified detail code.
258 * @param detail detail code for the resume event, such as <code>DebugEvent.STEP_OVER</code>
260 private void fireResumeEvent(int detail)
262 fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail));
266 * Fires a suspend event for this debug element with the specified detail code.
268 * @param detail detail code for the suspend event, such as <code>DebugEvent.BREAKPOINT</code>
270 private void fireSuspendEvent(int detail)
272 fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail));
276 * Fires a terminate event for this debug element.
278 private void fireTerminateEvent()
280 fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
284 * Fires a debug event.
286 * @param event debug event to fire
288 private static void fireEvent(DebugEvent event)
290 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });