1 package net.mograsim.plugin.launch;
3 import org.eclipse.core.resources.IMarkerDelta;
4 import org.eclipse.core.runtime.IStatus;
5 import org.eclipse.core.runtime.PlatformObject;
6 import org.eclipse.core.runtime.Status;
7 import org.eclipse.debug.core.DebugEvent;
8 import org.eclipse.debug.core.DebugException;
9 import org.eclipse.debug.core.DebugPlugin;
10 import org.eclipse.debug.core.ILaunch;
11 import org.eclipse.debug.core.ILaunchConfiguration;
12 import org.eclipse.debug.core.model.IBreakpoint;
13 import org.eclipse.debug.core.model.IDebugElement;
14 import org.eclipse.debug.core.model.IDebugTarget;
15 import org.eclipse.debug.core.model.IMemoryBlock;
16 import org.eclipse.debug.core.model.IMemoryBlockExtension;
17 import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
18 import org.eclipse.debug.core.model.IProcess;
19 import org.eclipse.debug.core.model.IStepFilters;
20 import org.eclipse.debug.core.model.IThread;
22 import net.mograsim.logic.model.LogicExecuter;
23 import net.mograsim.machine.Machine;
24 import net.mograsim.machine.MachineDefinition;
25 import net.mograsim.plugin.MograsimActivator;
27 public class MachineDebugTarget extends PlatformObject implements IDebugTarget, IMemoryBlockRetrievalExtension
29 private final ILaunch launch;
30 private final Machine machine;
31 private final LogicExecuter exec;
33 private boolean running;
35 public MachineDebugTarget(ILaunch launch, MachineDefinition machineDefinition)
38 this.machine = machineDefinition.createNew();
39 this.exec = new LogicExecuter(machine.getTimeline());
41 exec.startLiveExecution();
44 getLaunch().addDebugTarget(this);
48 public Machine getMachine()
54 public String getName() throws DebugException
56 return "Mograsim machine \"" + machine.getDefinition().getId() + '"';
60 public String getModelIdentifier()
62 return MograsimActivator.PLUGIN_ID;
66 public IDebugTarget getDebugTarget()
72 public ILaunch getLaunch()
77 public void setExecutionSpeed(double speed)
79 exec.setSpeedFactor(speed);
83 public boolean isSuspended()
85 return exec.isPaused();
89 public boolean canSuspend()
91 return !isTerminated() && !isSuspended();
95 public void suspend() throws DebugException
98 throwDebugException("Can't suspend a terminated MachineProcess");
100 throwDebugException("Can't suspend a suspended MachineProcess");
102 exec.pauseLiveExecution();
103 fireSuspendEvent(DebugEvent.CLIENT_REQUEST);
107 public boolean canResume()
109 return !isTerminated() && isSuspended();
113 public void resume() throws DebugException
116 throwDebugException("Can't resume a terminated MachineProcess");
118 throwDebugException("Can't resume a non-suspended MachineProcess");
120 exec.unpauseLiveExecution();
121 fireResumeEvent(DebugEvent.CLIENT_REQUEST);
125 public boolean isTerminated()
131 public boolean canTerminate()
133 return !isTerminated();
137 public void terminate() throws DebugException
142 exec.stopLiveExecution();
144 fireTerminateEvent();
148 public boolean supportsBreakpoint(IBreakpoint breakpoint)
154 public void breakpointAdded(IBreakpoint breakpoint)
156 // ignore; we don't support breakpoints
160 public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta)
162 // ignore; we don't support breakpoints
166 public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta)
168 // ignore; we don't support breakpoints
172 public boolean isDisconnected()
178 public boolean canDisconnect()
184 public void disconnect() throws DebugException
186 throw new DebugException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.NOT_SUPPORTED,
187 "Can't disconnect from a MachineDebugTarget", null));
191 public boolean supportsStorageRetrieval()
196 @SuppressWarnings("deprecation") // TODO can we throw a DebugException instead?
198 public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException
200 return new MainMemoryBlock(this, startAddress, length);
204 public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException
206 return new MainMemoryBlockExtension(this, expression, context);
210 public IProcess getProcess()
216 public boolean hasThreads() throws DebugException
222 public IThread[] getThreads() throws DebugException
224 return new IThread[0];
227 @SuppressWarnings("unchecked")
229 public <T> T getAdapter(Class<T> adapter)
231 if (adapter == IDebugElement.class)
234 // leave this here; maybe we implement IStepFilters someday
235 if (adapter == IStepFilters.class)
236 if (this instanceof IStepFilters)
237 return (T) getDebugTarget();
239 if (adapter == IDebugTarget.class)
240 return (T) getDebugTarget();
242 if (adapter == ILaunch.class)
243 return (T) getLaunch();
246 if (adapter == ILaunchConfiguration.class)
247 return (T) getLaunch().getLaunchConfiguration();
249 return super.getAdapter(adapter);
253 * Fires a creation event for this debug element.
255 private void fireCreationEvent()
257 fireEvent(new DebugEvent(this, DebugEvent.CREATE));
261 * Fires a resume for this debug element with the specified detail code.
263 * @param detail detail code for the resume event, such as <code>DebugEvent.STEP_OVER</code>
265 private void fireResumeEvent(int detail)
267 fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail));
271 * Fires a suspend event for this debug element with the specified detail code.
273 * @param detail detail code for the suspend event, such as <code>DebugEvent.BREAKPOINT</code>
275 private void fireSuspendEvent(int detail)
277 fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail));
281 * Fires a terminate event for this debug element.
283 private void fireTerminateEvent()
285 fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
289 * Fires a debug event.
291 * @param event debug event to fire
293 private static void fireEvent(DebugEvent event)
295 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
298 private static void throwDebugException(String message) throws DebugException
300 throw new DebugException(
301 new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, message, null));