Removed MachineProcess
[Mograsim.git] / plugins / net.mograsim.plugin.core / src / net / mograsim / plugin / launch / MachineDebugTarget.java
1 package net.mograsim.plugin.launch;
2
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;
21
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;
26
27 public class MachineDebugTarget extends PlatformObject implements IDebugTarget, IMemoryBlockRetrievalExtension
28 {
29         private final ILaunch launch;
30         private final Machine machine;
31         private final LogicExecuter exec;
32
33         private boolean running;
34
35         public MachineDebugTarget(ILaunch launch, MachineDefinition machineDefinition)
36         {
37                 this.launch = launch;
38                 this.machine = machineDefinition.createNew();
39                 this.exec = new LogicExecuter(machine.getTimeline());
40
41                 exec.startLiveExecution();
42                 running = true;
43
44                 getLaunch().addDebugTarget(this);
45                 fireCreationEvent();
46         }
47
48         public Machine getMachine()
49         {
50                 return machine;
51         }
52
53         @Override
54         public String getName() throws DebugException
55         {
56                 return "Mograsim machine \"" + machine.getDefinition().getId() + '"';
57         }
58
59         @Override
60         public String getModelIdentifier()
61         {
62                 return MograsimActivator.PLUGIN_ID;
63         }
64
65         @Override
66         public IDebugTarget getDebugTarget()
67         {
68                 return this;
69         }
70
71         @Override
72         public ILaunch getLaunch()
73         {
74                 return launch;
75         }
76
77         public void setExecutionSpeed(double speed)
78         {
79                 exec.setSpeedFactor(speed);
80         }
81
82         @Override
83         public boolean isSuspended()
84         {
85                 return exec.isPaused();
86         }
87
88         @Override
89         public boolean canSuspend()
90         {
91                 return !isTerminated() && !isSuspended();
92         }
93
94         @Override
95         public void suspend() throws DebugException
96         {
97                 if (isTerminated())
98                         throwDebugException("Can't suspend a terminated MachineProcess");
99                 if (isSuspended())
100                         throwDebugException("Can't suspend a suspended MachineProcess");
101
102                 exec.pauseLiveExecution();
103                 fireSuspendEvent(DebugEvent.CLIENT_REQUEST);
104         }
105
106         @Override
107         public boolean canResume()
108         {
109                 return !isTerminated() && isSuspended();
110         }
111
112         @Override
113         public void resume() throws DebugException
114         {
115                 if (isTerminated())
116                         throwDebugException("Can't resume a terminated MachineProcess");
117                 if (!isSuspended())
118                         throwDebugException("Can't resume a non-suspended MachineProcess");
119
120                 exec.unpauseLiveExecution();
121                 fireResumeEvent(DebugEvent.CLIENT_REQUEST);
122         }
123
124         @Override
125         public boolean isTerminated()
126         {
127                 return !running;
128         }
129
130         @Override
131         public boolean canTerminate()
132         {
133                 return !isTerminated();
134         }
135
136         @Override
137         public void terminate() throws DebugException
138         {
139                 if (isTerminated())
140                         return;
141
142                 exec.stopLiveExecution();
143                 running = false;
144                 fireTerminateEvent();
145         }
146
147         @Override
148         public boolean supportsBreakpoint(IBreakpoint breakpoint)
149         {
150                 return false;
151         }
152
153         @Override
154         public void breakpointAdded(IBreakpoint breakpoint)
155         {
156                 // ignore; we don't support breakpoints
157         }
158
159         @Override
160         public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta)
161         {
162                 // ignore; we don't support breakpoints
163         }
164
165         @Override
166         public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta)
167         {
168                 // ignore; we don't support breakpoints
169         }
170
171         @Override
172         public boolean isDisconnected()
173         {
174                 return false;
175         }
176
177         @Override
178         public boolean canDisconnect()
179         {
180                 return false;
181         }
182
183         @Override
184         public void disconnect() throws DebugException
185         {
186                 throw new DebugException(new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.NOT_SUPPORTED,
187                                 "Can't disconnect from a MachineDebugTarget", null));
188         }
189
190         @Override
191         public boolean supportsStorageRetrieval()
192         {
193                 return true;
194         }
195
196         @SuppressWarnings("deprecation") // TODO can we throw a DebugException instead?
197         @Override
198         public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException
199         {
200                 return new MainMemoryBlock(this, startAddress, length);
201         }
202
203         @Override
204         public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException
205         {
206                 return new MainMemoryBlockExtension(this, expression, context);
207         }
208
209         @Override
210         public IProcess getProcess()
211         {
212                 return null;
213         }
214
215         @Override
216         public boolean hasThreads() throws DebugException
217         {
218                 return false;
219         }
220
221         @Override
222         public IThread[] getThreads() throws DebugException
223         {
224                 return new IThread[0];
225         }
226
227         @SuppressWarnings("unchecked")
228         @Override
229         public <T> T getAdapter(Class<T> adapter)
230         {
231                 if (adapter == IDebugElement.class)
232                         return (T) this;
233
234                 // leave this here; maybe we implement IStepFilters someday
235                 if (adapter == IStepFilters.class)
236                         if (this instanceof IStepFilters)
237                                 return (T) getDebugTarget();
238
239                 if (adapter == IDebugTarget.class)
240                         return (T) getDebugTarget();
241
242                 if (adapter == ILaunch.class)
243                         return (T) getLaunch();
244
245                 // CONTEXTLAUNCHING
246                 if (adapter == ILaunchConfiguration.class)
247                         return (T) getLaunch().getLaunchConfiguration();
248
249                 return super.getAdapter(adapter);
250         }
251
252         /**
253          * Fires a creation event for this debug element.
254          */
255         private void fireCreationEvent()
256         {
257                 fireEvent(new DebugEvent(this, DebugEvent.CREATE));
258         }
259
260         /**
261          * Fires a resume for this debug element with the specified detail code.
262          *
263          * @param detail detail code for the resume event, such as <code>DebugEvent.STEP_OVER</code>
264          */
265         private void fireResumeEvent(int detail)
266         {
267                 fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail));
268         }
269
270         /**
271          * Fires a suspend event for this debug element with the specified detail code.
272          *
273          * @param detail detail code for the suspend event, such as <code>DebugEvent.BREAKPOINT</code>
274          */
275         private void fireSuspendEvent(int detail)
276         {
277                 fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail));
278         }
279
280         /**
281          * Fires a terminate event for this debug element.
282          */
283         private void fireTerminateEvent()
284         {
285                 fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
286         }
287
288         /**
289          * Fires a debug event.
290          *
291          * @param event debug event to fire
292          */
293         private static void fireEvent(DebugEvent event)
294         {
295                 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
296         }
297
298         private static void throwDebugException(String message) throws DebugException
299         {
300                 throw new DebugException(
301                                 new Status(IStatus.ERROR, MograsimActivator.PLUGIN_ID, DebugException.TARGET_REQUEST_FAILED, message, null));
302         }
303 }