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