mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 18:05:33 +02:00
214386: [run control][debug view][source lookup] When stepping fast (holding down F5 key) the IP in editor does not keep up.
This commit is contained in:
parent
e5930da951
commit
337235a75e
38 changed files with 1494 additions and 229 deletions
|
@ -0,0 +1,65 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.ISteppingControlParticipant;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
|
||||
/**
|
||||
* Base class for VM adapters used for implementing a debugger integration.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
|
||||
implements ISteppingControlParticipant
|
||||
{
|
||||
|
||||
public AbstractDebugVMAdapter(DsfSession session, SteppingController controller) {
|
||||
super(session);
|
||||
fController = controller;
|
||||
fController.addSteppingControlParticipant(this);
|
||||
}
|
||||
|
||||
private SteppingController fController;
|
||||
|
||||
@Override
|
||||
protected IVMProvider createViewModelProvider(IPresentationContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doneHandleEvent(Object event) {
|
||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
||||
final ISuspendedDMEvent suspendedEvent= (IRunControl.ISuspendedDMEvent) event;
|
||||
fController.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
fController.doneStepping(suspendedEvent.getDMContext(), AbstractDebugVMAdapter.this);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (fController != null) {
|
||||
fController.removeSteppingControlParticipant(this);
|
||||
fController = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,593 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 Wind River Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* This class builds on top of standard run control service to provide
|
||||
* functionality for step queuing and delaying. Step queuing essentially allows
|
||||
* user to press and hold the step key and achieve maximum stepping speed. If
|
||||
* this class is used, other service implementations, such as stack and
|
||||
* expressions, can use it to avoid requesting data from debugger back end if
|
||||
* another step is about to be executed.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public final class SteppingController implements IStepQueueManager
|
||||
{
|
||||
/**
|
||||
* Amount of time in milliseconds, that it takes the SteppingTimedOutEvent
|
||||
* event to be issued after a step is started.
|
||||
* @see SteppingTimedOutEvent
|
||||
*/
|
||||
public final static int STEPPING_TIMEOUT = 500;
|
||||
|
||||
/**
|
||||
* The depth of the step queue. In other words, the maximum number of steps
|
||||
* that are queued before the step queue manager is throwing them away.
|
||||
*/
|
||||
public final static int STEP_QUEUE_DEPTH = 1;
|
||||
|
||||
/**
|
||||
* The maximum delay (in milliseconds) between steps when synchronized
|
||||
* stepping is enabled. This also serves as a safeguard in the case stepping
|
||||
* control participants fail to indicate completion of event processing.
|
||||
*/
|
||||
public final static int MAX_STEP_DELAY= 1000;
|
||||
|
||||
/**
|
||||
* Indicates that the given context has been stepping for some time,
|
||||
* and the UI (views and actions) may need to be updated accordingly.
|
||||
*/
|
||||
public static final class SteppingTimedOutEvent extends AbstractDMEvent<IExecutionDMContext> {
|
||||
private SteppingTimedOutEvent(IExecutionDMContext execCtx) {
|
||||
super(execCtx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for clients interested in stepping control. When a stepping
|
||||
* control participant is registered with the stepping controller, it is
|
||||
* expected to call
|
||||
* {@link SteppingController#doneStepping(IExecutionDMContext, ISteppingControlParticipant)
|
||||
* doneStepping} as soon as a "step", i.e. a suspended event has been
|
||||
* processed. If synchronized stepping is enabled, further stepping is
|
||||
* blocked until all stepping control participants have indicated completion
|
||||
* of event processing or the maximum timeout
|
||||
* {@link SteppingController#MAX_STEP_DELAY} has been reached.
|
||||
*
|
||||
* @see SteppingController#addSteppingControlParticipant(ISteppingControlParticipant)
|
||||
* @see SteppingController#removeSteppingControlParticipant(ISteppingControlParticipant)
|
||||
*/
|
||||
public interface ISteppingControlParticipant {
|
||||
}
|
||||
|
||||
private static class StepRequest {
|
||||
StepType fStepType;
|
||||
StepRequest(StepType type) {
|
||||
fStepType = type;
|
||||
}
|
||||
}
|
||||
|
||||
private final DsfSession fSession;
|
||||
private final DsfServicesTracker fServicesTracker;
|
||||
|
||||
private IRunControl fRunControl;
|
||||
private int fQueueDepth = STEP_QUEUE_DEPTH;
|
||||
|
||||
private final Map<IExecutionDMContext,List<StepRequest>> fStepQueues = new HashMap<IExecutionDMContext,List<StepRequest>>();
|
||||
private final Map<IExecutionDMContext,Boolean> fTimedOutFlags = new HashMap<IExecutionDMContext,Boolean>();
|
||||
private final Map<IExecutionDMContext,ScheduledFuture<?>> fTimedOutFutures = new HashMap<IExecutionDMContext,ScheduledFuture<?>>();
|
||||
|
||||
/**
|
||||
* Records the time of the last step for an execution context.
|
||||
*/
|
||||
private final Map<IExecutionDMContext, Long> fLastStepTimes= new HashMap<IExecutionDMContext, Long>();
|
||||
|
||||
/**
|
||||
* Minimum step interval in milliseconds.
|
||||
*/
|
||||
private int fMinStepInterval= 0;
|
||||
|
||||
/**
|
||||
* Whether synchronized stepping is enabled.
|
||||
*/
|
||||
private boolean fSynchronizedStepping;
|
||||
|
||||
/**
|
||||
* Map of execution contexts for which a step is in progress.
|
||||
*/
|
||||
private final Map<IExecutionDMContext, List<ISteppingControlParticipant>> fStepInProgress = new HashMap<IExecutionDMContext, List<ISteppingControlParticipant>>();
|
||||
|
||||
/**
|
||||
* List of registered stepping control participants.
|
||||
*/
|
||||
private final List<ISteppingControlParticipant> fParticipants = Collections.synchronizedList(new ArrayList<ISteppingControlParticipant>());
|
||||
|
||||
/**
|
||||
* Property change listener. It updates the stepping control settings.
|
||||
*/
|
||||
private IPropertyChangeListener fPreferencesListener;
|
||||
|
||||
public SteppingController(DsfSession session) {
|
||||
fSession = session;
|
||||
fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
|
||||
final IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
|
||||
fPreferencesListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
handlePropertyChanged(store, event);
|
||||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
|
||||
enableSynchronizedStepping(store.getBoolean(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE));
|
||||
setMinimumStepInterval(store.getInt(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL));
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (fRunControl != null) {
|
||||
getSession().removeServiceEventListener(this);
|
||||
}
|
||||
|
||||
IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
store.removePropertyChangeListener(fPreferencesListener);
|
||||
|
||||
fServicesTracker.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables synchronized stepping mode.
|
||||
* In synchronized mode, after a step command is issued,
|
||||
* subsequent steps are blocked for the execution context
|
||||
* until {@link #doneStepping()} is called to indicate completion
|
||||
* of the processing for the last step.
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
public void enableSynchronizedStepping(boolean enable) {
|
||||
fSynchronizedStepping = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the minimum time (in milliseconds) to wait between steps.
|
||||
*
|
||||
* @param interval
|
||||
*/
|
||||
public void setMinimumStepInterval(int interval) {
|
||||
fMinStepInterval = interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register given stepping control participant.
|
||||
* <p>
|
||||
* Participants are obliged to call
|
||||
* {@link #doneStepping(IExecutionDMContext, ISteppingControlParticipant)}
|
||||
* when they have received and completed processing an
|
||||
* {@link ISuspendedDMEvent}. If synchronized stepping is enabled, further
|
||||
* stepping is disabled until all participants have indicated completion of
|
||||
* processing the event.
|
||||
* </p>
|
||||
*
|
||||
* @param participant
|
||||
*/
|
||||
public void addSteppingControlParticipant(ISteppingControlParticipant participant) {
|
||||
fParticipants.add(participant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister given stepping control participant.
|
||||
*
|
||||
* @param participant
|
||||
*/
|
||||
public void removeSteppingControlParticipant(final ISteppingControlParticipant participant) {
|
||||
fParticipants.remove(participant);
|
||||
// remove participant from steps in progress
|
||||
if (fSynchronizedStepping) {
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
|
||||
List<ISteppingControlParticipant> participants= fStepInProgress.get(disabledCtx);
|
||||
if (participants != null) {
|
||||
participants.remove(participant);
|
||||
if (participants.isEmpty()) {
|
||||
fStepInProgress.remove(disabledCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that participant has completed processing of the last step.
|
||||
*
|
||||
* @param execCtx
|
||||
*/
|
||||
public void doneStepping(final IExecutionDMContext execCtx, final ISteppingControlParticipant participant) {
|
||||
List<ISteppingControlParticipant> participants = fStepInProgress.get(execCtx);
|
||||
if (participants != null) {
|
||||
participants.remove(participant);
|
||||
if (participants.isEmpty()) {
|
||||
doneStepping(execCtx);
|
||||
}
|
||||
} else {
|
||||
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
|
||||
if (DMContexts.isAncestorOf(disabledCtx, execCtx)) {
|
||||
participants = fStepInProgress.get(disabledCtx);
|
||||
if (participants != null) {
|
||||
participants.remove(participant);
|
||||
if (participants.isEmpty()) {
|
||||
doneStepping(disabledCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DsfSession getSession() {
|
||||
return fSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* All access to this class should happen through this executor.
|
||||
* @return the executor this class is confined to
|
||||
*/
|
||||
public DsfExecutor getExecutor() {
|
||||
return getSession().getExecutor();
|
||||
}
|
||||
|
||||
private DsfServicesTracker getServicesTracker() {
|
||||
return fServicesTracker;
|
||||
}
|
||||
|
||||
private IRunControl getRunControl() {
|
||||
if (fRunControl == null) {
|
||||
fRunControl = getServicesTracker().getService(IRunControl.class);
|
||||
getSession().addServiceEventListener(this, null);
|
||||
}
|
||||
return fRunControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a step command can be queued up for given context.
|
||||
*/
|
||||
public void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm) {
|
||||
if (doCanEnqueueStep(execCtx, stepType)) {
|
||||
rm.setData(true);
|
||||
rm.done();
|
||||
} else {
|
||||
getRunControl().canStep(execCtx, stepType, rm);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doCanEnqueueStep(IExecutionDMContext execCtx, StepType stepType) {
|
||||
return getRunControl().isStepping(execCtx) && !isSteppingTimedOut(execCtx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the next step on the given execution context should be delayed
|
||||
* based on the configured step delay.
|
||||
*
|
||||
* @param execCtx
|
||||
* @return <code>true</code> if the step should be delayed
|
||||
*/
|
||||
private boolean shouldDelayStep(IExecutionDMContext execCtx) {
|
||||
return getStepDelay(execCtx) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the delay in milliseconds before the next step for the given context may be executed.
|
||||
*
|
||||
* @param execCtx
|
||||
* @return the number of milliseconds before the next possible step
|
||||
*/
|
||||
private int getStepDelay(IExecutionDMContext execCtx) {
|
||||
if (fMinStepInterval > 0) {
|
||||
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
|
||||
if (execCtx.equals(lastStepCtx) || DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
|
||||
long now = System.currentTimeMillis();
|
||||
int delay= (int) (fLastStepTimes.get(lastStepCtx) + fMinStepInterval - now);
|
||||
return Math.max(delay, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void updateLastStepTime(IExecutionDMContext execCtx) {
|
||||
long now = System.currentTimeMillis();
|
||||
fLastStepTimes.put(execCtx, now);
|
||||
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
|
||||
if (!execCtx.equals(lastStepCtx) && DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
|
||||
fLastStepTimes.put(lastStepCtx, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getLastStepTime(IExecutionDMContext execCtx) {
|
||||
if (fLastStepTimes.containsKey(execCtx)) {
|
||||
return fLastStepTimes.get(execCtx);
|
||||
}
|
||||
for (IExecutionDMContext lastStepCtx : fLastStepTimes.keySet()) {
|
||||
if (DMContexts.isAncestorOf(execCtx, lastStepCtx)) {
|
||||
return fLastStepTimes.get(lastStepCtx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of step commands that are queued for given execution
|
||||
* context.
|
||||
*/
|
||||
public int getPendingStepCount(IExecutionDMContext execCtx) {
|
||||
List<StepRequest> stepQueue = fStepQueues.get(execCtx);
|
||||
if (stepQueue == null) return 0;
|
||||
return stepQueue.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a step command to the execution queue for given context.
|
||||
* @param execCtx Execution context that should perform the step.
|
||||
* @param stepType Type of step to execute.
|
||||
*/
|
||||
public void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
|
||||
if (shouldDelayStep(execCtx)) {
|
||||
if (doCanEnqueueStep(execCtx, stepType)) {
|
||||
doEnqueueStep(execCtx, stepType);
|
||||
if (!getRunControl().isStepping(execCtx)) {
|
||||
processStepQueue(execCtx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
getRunControl().canStep(
|
||||
execCtx, stepType, new DataRequestMonitor<Boolean>(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess() && getData()) {
|
||||
if (isSteppingDisabled(execCtx)) {
|
||||
doEnqueueStep(execCtx, stepType);
|
||||
} else {
|
||||
doStep(execCtx, stepType);
|
||||
}
|
||||
} else if (doCanEnqueueStep(execCtx, stepType)) {
|
||||
doEnqueueStep(execCtx, stepType);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void doStep(final IExecutionDMContext execCtx, final StepType stepType) {
|
||||
if (fSynchronizedStepping) {
|
||||
disableStepping(execCtx);
|
||||
}
|
||||
updateLastStepTime(execCtx);
|
||||
getRunControl().step(execCtx, stepType, new RequestMonitor(getExecutor(), null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the given step for later execution.
|
||||
*
|
||||
* @param execCtx
|
||||
* @param stepType
|
||||
*/
|
||||
private void doEnqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
|
||||
List<StepRequest> stepQueue = fStepQueues.get(execCtx);
|
||||
if (stepQueue == null) {
|
||||
stepQueue = new LinkedList<StepRequest>();
|
||||
fStepQueues.put(execCtx, stepQueue);
|
||||
}
|
||||
if (stepQueue.size() < fQueueDepth) {
|
||||
stepQueue.add(new StepRequest(stepType));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the step instruction for the given context has timed out.
|
||||
*/
|
||||
public boolean isSteppingTimedOut(IExecutionDMContext execCtx) {
|
||||
for (IExecutionDMContext timedOutCtx : fTimedOutFlags.keySet()) {
|
||||
if (execCtx.equals(timedOutCtx) || DMContexts.isAncestorOf(execCtx, timedOutCtx)) {
|
||||
return fTimedOutFlags.get(timedOutCtx);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process next step on queue if any.
|
||||
* @param execCtx
|
||||
*/
|
||||
private void processStepQueue(final IExecutionDMContext execCtx) {
|
||||
if (isSteppingDisabled(execCtx)) {
|
||||
return;
|
||||
}
|
||||
if (fStepQueues.containsKey(execCtx)) {
|
||||
final int stepDelay = getStepDelay(execCtx);
|
||||
if (stepDelay > 0) {
|
||||
getExecutor().schedule(new DsfRunnable() {
|
||||
public void run() {
|
||||
processStepQueue(execCtx);
|
||||
}
|
||||
}, stepDelay, TimeUnit.MILLISECONDS);
|
||||
return;
|
||||
}
|
||||
List<StepRequest> queue = fStepQueues.get(execCtx);
|
||||
final StepRequest request = queue.remove(queue.size() - 1);
|
||||
if (queue.isEmpty()) fStepQueues.remove(execCtx);
|
||||
getRunControl().canStep(
|
||||
execCtx, request.fStepType,
|
||||
new DataRequestMonitor<Boolean>(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess() && getData()) {
|
||||
doStep(execCtx, request.fStepType);
|
||||
} else {
|
||||
// For whatever reason we can't step anymore, so clear out
|
||||
// the step queue.
|
||||
fStepQueues.remove(execCtx);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable stepping for the given execution context.
|
||||
*
|
||||
* @param execCtx
|
||||
*/
|
||||
private void disableStepping(IExecutionDMContext execCtx) {
|
||||
fStepInProgress.put(execCtx, new ArrayList<ISteppingControlParticipant>(fParticipants));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that processing of the last step has completed and
|
||||
* the next step can be issued.
|
||||
*
|
||||
* @param execCtx
|
||||
*/
|
||||
private void doneStepping(final IExecutionDMContext execCtx) {
|
||||
if (fSynchronizedStepping) {
|
||||
enableStepping(execCtx);
|
||||
processStepQueue(execCtx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable stepping for the given execution context.
|
||||
*
|
||||
* @param execCtx
|
||||
*/
|
||||
private void enableStepping(final IExecutionDMContext execCtx) {
|
||||
fStepInProgress.remove(execCtx);
|
||||
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
|
||||
if (DMContexts.isAncestorOf(disabledCtx, execCtx)) {
|
||||
fStepInProgress.remove(disabledCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSteppingDisabled(IExecutionDMContext execCtx) {
|
||||
if (fSynchronizedStepping) {
|
||||
boolean disabled= fStepInProgress.containsKey(execCtx);
|
||||
if (!disabled) {
|
||||
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
|
||||
if (DMContexts.isAncestorOf(execCtx, disabledCtx)) {
|
||||
disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disabled) {
|
||||
long now = System.currentTimeMillis();
|
||||
long lastStepTime = getLastStepTime(execCtx);
|
||||
if (now - lastStepTime > MAX_STEP_DELAY) {
|
||||
enableStepping(execCtx);
|
||||
disabled = false;
|
||||
}
|
||||
}
|
||||
return disabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE.equals(property)) {
|
||||
enableSynchronizedStepping(store.getBoolean(property));
|
||||
} else if (IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL.equals(property)) {
|
||||
setMinimumStepInterval(store.getInt(property));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final ISuspendedDMEvent e) {
|
||||
// Take care of the stepping time out
|
||||
fTimedOutFlags.remove(e.getDMContext());
|
||||
ScheduledFuture<?> future = fTimedOutFutures.remove(e.getDMContext());
|
||||
if (future != null) future.cancel(false);
|
||||
|
||||
// Check if there's a step pending, if so execute it
|
||||
processStepQueue(e.getDMContext());
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final IResumedDMEvent e) {
|
||||
if (e.getReason().equals(StateChangeReason.STEP)) {
|
||||
fTimedOutFlags.put(e.getDMContext(), Boolean.FALSE);
|
||||
// We shouldn't have a stepping timeout running unless we get two
|
||||
// stepping events in a row without a suspended, which would be a
|
||||
// protocol error.
|
||||
assert !fTimedOutFutures.containsKey(e.getDMContext());
|
||||
fTimedOutFutures.put(
|
||||
e.getDMContext(),
|
||||
getExecutor().schedule(
|
||||
new DsfRunnable() { public void run() {
|
||||
fTimedOutFutures.remove(e.getDMContext());
|
||||
|
||||
if (getSession().isActive()) {
|
||||
// Issue the stepping time-out event.
|
||||
getSession().dispatchEvent(
|
||||
new SteppingTimedOutEvent(e.getDMContext()),
|
||||
null);
|
||||
}
|
||||
}},
|
||||
STEPPING_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(SteppingTimedOutEvent e) {
|
||||
fTimedOutFlags.put(e.getDMContext(), Boolean.TRUE);
|
||||
enableStepping(e.getDMContext());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
||||
|
@ -37,6 +38,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|||
/**
|
||||
* Abstract implementation of a container view model node.
|
||||
* Clients need to implement {@link #updateLabelInSessionThread(ILabelUpdate[])}.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public abstract class AbstractContainerVMNode extends AbstractDMVMNode implements IElementLabelProvider {
|
||||
|
@ -87,6 +90,11 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement
|
|||
if (dmc instanceof IContainerDMContext) {
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
if (dmc instanceof IContainerDMContext)
|
||||
{
|
||||
return IModelDelta.CONTENT;
|
||||
}
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
if (dmc instanceof IContainerDMContext)
|
||||
{
|
||||
|
@ -129,6 +137,15 @@ public abstract class AbstractContainerVMNode extends AbstractDMVMNode implement
|
|||
if (dmc instanceof IContainerDMContext) {
|
||||
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
|
||||
}
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
// Stepping time-out indicates that a step operation is taking
|
||||
// a long time, and the view needs to be refreshed to show
|
||||
// the user that the program is running.
|
||||
// If the step was issued for the whole container refresh
|
||||
// the whole container.
|
||||
if (dmc instanceof IContainerDMContext) {
|
||||
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
|
||||
}
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
// Stepping time-out indicates that a step operation is taking
|
||||
// a long time, and the view needs to be refreshed to show
|
||||
|
|
|
@ -54,7 +54,7 @@ import org.eclipse.jface.viewers.IStructuredSelection;
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
||||
|
@ -81,20 +81,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
|
||||
fPreferencesListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|
||||
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property)) {
|
||||
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
|
||||
} else {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, null);
|
||||
}
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
handlePropertyChanged(store, event);
|
||||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
@ -128,30 +115,33 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Object event) {
|
||||
public void handleEvent(Object event, final RequestMonitor rm) {
|
||||
if (event instanceof DoubleClickEvent && !isDisposed()) {
|
||||
final ISelection selection= ((DoubleClickEvent) event).getSelection();
|
||||
if (selection instanceof IStructuredSelection) {
|
||||
Object element= ((IStructuredSelection) selection).getFirstElement();
|
||||
if (element instanceof IncompleteStackVMContext) {
|
||||
IncompleteStackVMContext incStackVmc = ((IncompleteStackVMContext) element);
|
||||
IVMNode node = ((IncompleteStackVMContext) element).getVMNode();
|
||||
if (incStackVmc.getVMNode() instanceof StackFramesVMNode) {
|
||||
IVMNode node = incStackVmc.getVMNode();
|
||||
if (node instanceof StackFramesVMNode && node.getVMProvider() == this) {
|
||||
IExecutionDMContext exeCtx= incStackVmc.getExecutionDMContext();
|
||||
((StackFramesVMNode) node).incrementStackFrameLimit(exeCtx);
|
||||
// replace double click event with expand stack event
|
||||
final ExpandStackEvent expandStackEvent = new ExpandStackEvent(exeCtx);
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(expandStackEvent);
|
||||
handleEvent(expandStackEvent, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rm != null) {
|
||||
rm.done();
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.handleEvent(event);
|
||||
super.handleEvent(event, rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -177,7 +167,7 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
ScheduledFuture<?> future= fRefreshStackFramesFutures.get(exeContext);
|
||||
if (future != null && !isDisposed()) {
|
||||
fRefreshStackFramesFutures.remove(exeContext);
|
||||
handleEvent(new FullStackRefreshEvent(exeContext));
|
||||
handleEvent(new FullStackRefreshEvent(exeContext), null);
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
@ -276,4 +266,21 @@ public class AbstractLaunchVMProvider extends AbstractDMVMProvider
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE.equals(property)
|
||||
|| IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT.equals(property)) {
|
||||
if (store.getBoolean(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE)) {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, store.getInt(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT));
|
||||
} else {
|
||||
getPresentationContext().setProperty(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, null);
|
||||
}
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
||||
|
@ -50,6 +51,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
|||
/**
|
||||
* Abstract implementation of a thread view model node.
|
||||
* Clients need to implement {@link #updateLabelInSessionThread(ILabelUpdate[])}.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public abstract class AbstractThreadVMNode extends AbstractDMVMNode
|
||||
|
@ -112,6 +115,15 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
|
|||
rm.done();
|
||||
return;
|
||||
}
|
||||
} else if (e instanceof SteppingTimedOutEvent &&
|
||||
((SteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext)
|
||||
{
|
||||
// The timed out event occured on a container and not on a thread. Do not
|
||||
// return a context for this event, which will force the view model to generate
|
||||
// a delta for all the threads.
|
||||
rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
} else if (e instanceof ISteppingTimedOutEvent &&
|
||||
((ISteppingTimedOutEvent)e).getDMContext() instanceof IContainerDMContext)
|
||||
{
|
||||
|
@ -232,6 +244,8 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
|
|||
return IModelDelta.NO_CHANGE;
|
||||
} else if (e instanceof FullStackRefreshEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
|
@ -271,6 +285,12 @@ public abstract class AbstractThreadVMNode extends AbstractDMVMNode
|
|||
// and a fixed delay. Refresh the whole thread upon this event.
|
||||
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
// Stepping time-out indicates that a step operation is taking
|
||||
// a long time, and the view needs to be refreshed to show
|
||||
// the user that the program is running.
|
||||
parentDelta.addNode(createVMContext(dmc), IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
// Stepping time-out indicates that a step operation is taking
|
||||
// a long time, and the view needs to be refreshed to show
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.eclipse.jface.viewers.TreePath;
|
|||
* The underlying base update policy is considered for container contexts only.
|
||||
* In other cases the cache data is always flushed.
|
||||
* </p>
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public class DelayedStackRefreshUpdatePolicy extends UpdatePolicyDecorator {
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
|||
|
||||
/**
|
||||
* Event to increase the stack frame limit for an execution context.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public class ExpandStackEvent extends AbstractDMEvent<IExecutionDMContext> {
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
|||
/**
|
||||
* Indicates the end of a sequence of steps. Should be handled like a suspended
|
||||
* event to trigger a full refresh of stack frames.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public class FullStackRefreshEvent extends AbstractDMEvent<IExecutionDMContext> {
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch;
|
|||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
public class LaunchVMUpdateMessages extends NLS {
|
||||
|
||||
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.LaunchVMUpdateMessages";//$NON-NLS-1$
|
||||
|
|
|
@ -22,10 +22,11 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
|||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack2;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
|
@ -33,6 +34,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent;
|
|||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager.ISteppingTimedOutEvent;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
|
@ -65,6 +67,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
|
||||
/**
|
||||
* View model context representing the end of an incomplete stack.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public class IncompleteStackVMContext extends AbstractVMContext {
|
||||
private final int fLevel;
|
||||
|
@ -320,13 +324,16 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
if (idx != 0) return;
|
||||
|
||||
final IExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExecutionDMContext.class);
|
||||
if (execDmc == null) {
|
||||
return;
|
||||
}
|
||||
IRunControl runControlService = getServicesTracker().getService(IRunControl.class);
|
||||
StepQueueManager stepQueueMgrService = getServicesTracker().getService(StepQueueManager.class);
|
||||
if (execDmc == null || runControlService == null || stepQueueMgrService == null) return;
|
||||
SteppingController stepQueueMgr = (SteppingController) execDmc.getAdapter(SteppingController.class);
|
||||
if (runControlService == null || stepQueueMgr == null) return;
|
||||
|
||||
String imageKey = null;
|
||||
if (runControlService.isSuspended(execDmc) ||
|
||||
(runControlService.isStepping(execDmc) && !stepQueueMgrService.isSteppingTimedOut(execDmc)))
|
||||
(runControlService.isStepping(execDmc) && !stepQueueMgr.isSteppingTimedOut(execDmc)))
|
||||
{
|
||||
imageKey = IDebugUIConstants.IMG_OBJS_STACKFRAME;
|
||||
} else {
|
||||
|
@ -409,7 +416,9 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
return IModelDelta.CONTENT | IModelDelta.EXPAND | IModelDelta.SELECT;
|
||||
} else if (e instanceof FullStackRefreshEvent) {
|
||||
return IModelDelta.CONTENT | IModelDelta.EXPAND;
|
||||
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
return IModelDelta.CONTENT;
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
return IModelDelta.SELECT | IModelDelta.EXPAND;
|
||||
|
@ -461,8 +470,10 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
clearStackFrameLimit( ((ISuspendedDMEvent)e).getDMContext() );
|
||||
IExecutionDMContext execDmc = ((ISuspendedDMEvent)e).getDMContext();
|
||||
buildDeltaForSuspendedEvent(execDmc, execDmc, parent, nodeOffset, rm);
|
||||
} else if (e instanceof StepQueueManager.ISteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((StepQueueManager.ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof SteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((SteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof ISteppingTimedOutEvent) {
|
||||
buildDeltaForSteppingTimedOutEvent((ISteppingTimedOutEvent)e, parent, nodeOffset, rm);
|
||||
} else if (e instanceof ModelProxyInstalledEvent) {
|
||||
buildDeltaForModelProxyInstalledEvent(parent, nodeOffset, rm);
|
||||
} else if (e instanceof ExpandStackEvent) {
|
||||
|
@ -549,7 +560,13 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
rm.done();
|
||||
}
|
||||
|
||||
private void buildDeltaForSteppingTimedOutEvent(final StepQueueManager.ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
private void buildDeltaForSteppingTimedOutEvent(final SteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
// Repaint the stack frame images to have the running symbol.
|
||||
//parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
private void buildDeltaForSteppingTimedOutEvent(final ISteppingTimedOutEvent e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor rm) {
|
||||
// Repaint the stack frame images to have the running symbol.
|
||||
//parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
|
@ -662,6 +679,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
* Get the current active stack frame limit. If no limit is applicable {@link Integer.MAX_VALUE} is returned.
|
||||
*
|
||||
* @return the current stack frame limit
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public int getStackFrameLimit(IExecutionDMContext execCtx) {
|
||||
if (fTemporaryLimits.containsKey(execCtx)) {
|
||||
|
@ -691,6 +710,8 @@ public class StackFramesVMNode extends AbstractDMVMNode
|
|||
/**
|
||||
* Increment the stack frame limit by the default increment.
|
||||
* This implementation doubles the current limit.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public void incrementStackFrameLimit(IExecutionDMContext execCtx) {
|
||||
final int stackFrameLimit= getStackFrameLimit(execCtx);
|
||||
|
|
|
@ -12,6 +12,7 @@ package org.eclipse.dd.dsf.debug.internal.ui.preferences;
|
|||
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.jface.preference.BooleanFieldEditor;
|
||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||
|
@ -33,7 +34,7 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
|
|||
* Mandatory default constructor (executable extension).
|
||||
*/
|
||||
public DsfDebugPreferencePage() {
|
||||
super(GRID);
|
||||
super(FLAT);
|
||||
IPreferenceStore store= DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||
setPreferenceStore(store);
|
||||
setDescription(MessagesForPreferences.DsfDebugPreferencePage_description);
|
||||
|
@ -53,26 +54,54 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
|
|||
|
||||
@Override
|
||||
protected void createFieldEditors() {
|
||||
Group performanceGroup= new Group(getFieldEditorParent(), SWT.NONE);
|
||||
final Composite parent= getFieldEditorParent();
|
||||
final GridLayout layout= new GridLayout();
|
||||
layout.marginWidth= 0;
|
||||
parent.setLayout(layout);
|
||||
|
||||
Group performanceGroup= new Group(parent, SWT.NONE);
|
||||
performanceGroup.setText(MessagesForPreferences.DsfDebugPreferencePage_performanceGroup_label);
|
||||
performanceGroup.setLayout(new GridLayout());
|
||||
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.verticalIndent= 5;
|
||||
performanceGroup.setLayoutData(gd);
|
||||
|
||||
Composite innerParent= new Composite(performanceGroup, SWT.NONE);
|
||||
innerParent.setLayout(new GridLayout());
|
||||
innerParent.setLayoutData(gd);
|
||||
|
||||
GridLayout groupLayout= new GridLayout(3, false);
|
||||
performanceGroup.setLayout(groupLayout);
|
||||
performanceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
|
||||
// stack frame limit
|
||||
IntegerFieldEditor limitEditor= new IntegerWithBooleanFieldEditor(
|
||||
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE,
|
||||
IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_limitStackFrames_label,
|
||||
innerParent);
|
||||
performanceGroup);
|
||||
|
||||
limitEditor.setValidRange(1, Integer.MAX_VALUE);
|
||||
limitEditor.fillIntoGrid(innerParent, 3);
|
||||
limitEditor.fillIntoGrid(performanceGroup, 3);
|
||||
addField(limitEditor);
|
||||
|
||||
// sync stepping speed
|
||||
BooleanFieldEditor syncSteppingEditor= new BooleanFieldEditor(
|
||||
IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_syncStepping_label,
|
||||
performanceGroup);
|
||||
|
||||
syncSteppingEditor.fillIntoGrid(performanceGroup, 3);
|
||||
addField(syncSteppingEditor);
|
||||
|
||||
// minimum step interval
|
||||
IntegerFieldEditor minIntervalEditor= new IntegerFieldEditor(
|
||||
IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_minStepInterval_label,
|
||||
performanceGroup);
|
||||
|
||||
minIntervalEditor.setValidRange(0, 10000);
|
||||
minIntervalEditor.fillIntoGrid(performanceGroup, 3);
|
||||
addField(minIntervalEditor);
|
||||
|
||||
// need to set layout again
|
||||
performanceGroup.setLayout(groupLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustGridLayout() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,8 +14,10 @@ import org.eclipse.jface.preference.IntegerFieldEditor;
|
|||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
|
||||
/**
|
||||
* An integer field editor with an enablement check box.
|
||||
|
@ -42,20 +44,19 @@ public class IntegerWithBooleanFieldEditor extends IntegerFieldEditor {
|
|||
super.doFillIntoGrid(parent, numColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfControls() {
|
||||
return super.getNumberOfControls() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustForNumColumns(int numColumns) {
|
||||
// the checkbox uses one column
|
||||
super.adjustForNumColumns(numColumns - 1);
|
||||
}
|
||||
|
||||
private Button getCheckboxControl(Composite parent) {
|
||||
if (fCheckbox == null) {
|
||||
fCheckbox= new Button(parent, SWT.CHECK);
|
||||
Composite inner= new Composite(parent, SWT.NULL);
|
||||
final GridLayout layout= new GridLayout(2, false);
|
||||
layout.marginWidth = 0;
|
||||
inner.setLayout(layout);
|
||||
fCheckbox= new Button(inner, SWT.CHECK);
|
||||
fCheckbox.setFont(parent.getFont());
|
||||
fCheckbox.setText(getLabelText());
|
||||
// create and hide label from base class
|
||||
Label label = getLabelControl(inner);
|
||||
label.setText(""); //$NON-NLS-1$
|
||||
label.setVisible(false);
|
||||
fCheckbox.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
|
@ -65,11 +66,22 @@ public class IntegerWithBooleanFieldEditor extends IntegerFieldEditor {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
checkParent(fCheckbox, parent);
|
||||
checkParent(fCheckbox.getParent(), parent);
|
||||
}
|
||||
return fCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getLabelControl(Composite parent) {
|
||||
final Label label= getLabelControl();
|
||||
if (label == null) {
|
||||
return super.getLabelControl(parent);
|
||||
} else {
|
||||
checkParent(label.getParent(), parent);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
protected void valueChanged(boolean oldValue, boolean newValue) {
|
||||
setPresentsDefaultValue(false);
|
||||
if (oldValue != newValue) {
|
||||
|
|
|
@ -20,8 +20,12 @@ class MessagesForPreferences extends NLS {
|
|||
|
||||
public static String DsfDebugPreferencePage_description;
|
||||
public static String DsfDebugPreferencePage_limitStackFrames_label;
|
||||
|
||||
public static String DsfDebugPreferencePage_minStepInterval_label;
|
||||
public static String DsfDebugPreferencePage_performanceGroup_label;
|
||||
|
||||
public static String DsfDebugPreferencePage_syncStepping_label;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);
|
||||
|
|
|
@ -14,8 +14,10 @@ import org.eclipse.jface.preference.StringFieldEditor;
|
|||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
|
||||
/**
|
||||
* A string field editor with an enablement check box.
|
||||
|
@ -47,20 +49,19 @@ public class StringWithBooleanFieldEditor extends StringFieldEditor {
|
|||
super.doFillIntoGrid(parent, numColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfControls() {
|
||||
return super.getNumberOfControls() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustForNumColumns(int numColumns) {
|
||||
// the checkbox uses one column
|
||||
super.adjustForNumColumns(numColumns - 1);
|
||||
}
|
||||
|
||||
private Button getCheckboxControl(Composite parent) {
|
||||
if (fCheckbox == null) {
|
||||
fCheckbox= new Button(parent, SWT.CHECK);
|
||||
Composite inner= new Composite(parent, SWT.NULL);
|
||||
final GridLayout layout= new GridLayout(2, false);
|
||||
layout.marginWidth = 0;
|
||||
inner.setLayout(layout);
|
||||
fCheckbox= new Button(inner, SWT.CHECK);
|
||||
fCheckbox.setFont(parent.getFont());
|
||||
fCheckbox.setText(getLabelText());
|
||||
// create and hide label from base class
|
||||
Label label = getLabelControl(inner);
|
||||
label.setText(""); //$NON-NLS-1$
|
||||
label.setVisible(false);
|
||||
fCheckbox.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
|
@ -70,11 +71,22 @@ public class StringWithBooleanFieldEditor extends StringFieldEditor {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
checkParent(fCheckbox, parent);
|
||||
checkParent(fCheckbox.getParent(), parent);
|
||||
}
|
||||
return fCheckbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getLabelControl(Composite parent) {
|
||||
final Label label= getLabelControl();
|
||||
if (label == null) {
|
||||
return super.getLabelControl(parent);
|
||||
} else {
|
||||
checkParent(label.getParent(), parent);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
protected void valueChanged(boolean oldValue, boolean newValue) {
|
||||
setPresentsDefaultValue(false);
|
||||
if (oldValue != newValue) {
|
||||
|
|
|
@ -11,4 +11,6 @@
|
|||
|
||||
DsfDebugPreferencePage_description=General settings for debugging with DSF:
|
||||
DsfDebugPreferencePage_limitStackFrames_label=Limit number of stack frames to
|
||||
DsfDebugPreferencePage_minStepInterval_label=Minimum interval between steps (in milliseconds)
|
||||
DsfDebugPreferencePage_performanceGroup_label=Performance
|
||||
DsfDebugPreferencePage_syncStepping_label=Synchronize stepping speed with UI updates
|
||||
|
|
|
@ -12,7 +12,9 @@ package org.eclipse.dd.dsf.debug.ui;
|
|||
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
|
||||
|
||||
/**
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IDsfDebugUIConstants {
|
||||
|
||||
/**
|
||||
|
@ -60,15 +62,33 @@ public interface IDsfDebugUIConstants {
|
|||
* Integer preference to control the maximum amount of stack frames to
|
||||
* retrieve from the backend. Default value is 10.
|
||||
* @see {@link #PREF_STACK_FRAME_LIMIT_ENABLE}
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public static final String PREF_STACK_FRAME_LIMIT = "stackFrameLimit"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Boolean preference whether to apply the stack frame limit preference.
|
||||
* Boolean preference whether to apply the stack frame limit preference. Default is <code>true</code>.
|
||||
* @see {@link #PREF_STACK_FRAME_LIMIT}
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public static final String PREF_STACK_FRAME_LIMIT_ENABLE = "stackFrameLimitEnable"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Boolean preference whether to keep stepping speed in sync with UI updates. Default is <code>true</code>.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public static final String PREF_SYNCHRONIZED_STEPPING_ENABLE = "synchronizedSteppingEnable"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Integer preference to enforce a minimum time interval between steps. Default is <code>0</code>.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public static final String PREF_MIN_STEP_INTERVAL= "minStepInterval"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Help prefixes.
|
||||
*/
|
||||
|
@ -85,5 +105,8 @@ public interface IDsfDebugUIConstants {
|
|||
public static final String DETAIL_PANE_WORD_WRAP_ACTION = PREFIX + "detail_pane_word_wrap_action_context"; //$NON-NLS-1$
|
||||
public static final String DETAIL_PANE_MAX_LENGTH_ACTION = PREFIX + "detail_pane_max_length_action_context"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
public static final String PREFERENCE_PAGE= PREFIX + "preference_page_context"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -58,5 +58,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
|
|||
*/
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, 10);
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE, true);
|
||||
}
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE, true);
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@ import org.eclipse.core.runtime.Status;
|
|||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
|
@ -33,10 +35,36 @@ public abstract class DsfCommandRunnable extends DsfRunnable {
|
|||
public IRunControl getRunControl() {
|
||||
return fTracker.getService(IRunControl.class);
|
||||
}
|
||||
public StepQueueManager getStepQueueMgr() {
|
||||
/**
|
||||
* @deprecated Use {@link #getStepQueueManager()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public StepQueueManager getStepQueueMgr() {
|
||||
return fTracker.getService(StepQueueManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
public IStepQueueManager getStepQueueManager() {
|
||||
// for backwards compatibility
|
||||
IStepQueueManager mgr= getStepQueueMgr();
|
||||
if (mgr != null) {
|
||||
return mgr;
|
||||
}
|
||||
return getSteppingController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
public SteppingController getSteppingController() {
|
||||
if (fContext != null) {
|
||||
return (SteppingController) fContext.getAdapter(SteppingController.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DsfCommandRunnable(DsfServicesTracker servicesTracker, Object element, IDebugCommandRequest request) {
|
||||
fTracker = servicesTracker;
|
||||
if (element instanceof IDMVMContext) {
|
||||
|
@ -56,7 +84,7 @@ public abstract class DsfCommandRunnable extends DsfRunnable {
|
|||
}
|
||||
if (getContext() == null) {
|
||||
fRequest.setStatus(makeError("Selected object does not support run control.", null)); //$NON-NLS-1$
|
||||
} else if (getRunControl() == null || getStepQueueMgr() == null) {
|
||||
} else if (getRunControl() == null || getStepQueueManager() == null) {
|
||||
fRequest.setStatus(makeError("Run Control not available", null)); //$NON-NLS-1$
|
||||
} else {
|
||||
doExecute();
|
||||
|
|
|
@ -49,7 +49,7 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
|
|||
final StepType stepType= getStepType();
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().canEnqueueStep(
|
||||
getStepQueueManager().canEnqueueStep(
|
||||
getContext(), stepType,
|
||||
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
|
||||
@Override
|
||||
|
@ -71,7 +71,7 @@ public class DsfStepIntoCommand implements IStepIntoHandler {
|
|||
final StepType stepType= getStepType();
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), stepType);
|
||||
getStepQueueManager().enqueueStep(getContext(), stepType);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -49,7 +49,7 @@ public class DsfStepOverCommand implements IStepOverHandler {
|
|||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
final StepType stepType= getStepType();
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().canEnqueueStep(
|
||||
getStepQueueManager().canEnqueueStep(
|
||||
getContext(), stepType,
|
||||
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
|
||||
@Override
|
||||
|
@ -71,7 +71,7 @@ public class DsfStepOverCommand implements IStepOverHandler {
|
|||
final StepType stepType= getStepType();
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), stepType);
|
||||
getStepQueueManager().enqueueStep(getContext(), stepType);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DsfStepReturnCommand implements IStepReturnHandler {
|
|||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().canEnqueueStep(
|
||||
getStepQueueManager().canEnqueueStep(
|
||||
getContext(), StepType.STEP_RETURN,
|
||||
new DataRequestMonitor<Boolean>(ImmediateExecutor.getInstance(), null) {
|
||||
@Override
|
||||
|
@ -67,7 +67,7 @@ public class DsfStepReturnCommand implements IStepReturnHandler {
|
|||
|
||||
fExecutor.submit(new DsfCommandRunnable(fTracker, request.getElements()[0], request) {
|
||||
@Override public void doExecute() {
|
||||
getStepQueueMgr().enqueueStep(getContext(), StepType.STEP_RETURN);
|
||||
getStepQueueManager().enqueueStep(getContext(), StepType.STEP_RETURN);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -33,10 +33,14 @@ import org.eclipse.dd.dsf.concurrent.Query;
|
|||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.ISteppingControlParticipant;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController.SteppingTimedOutEvent;
|
||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMData;
|
||||
|
@ -86,7 +90,7 @@ import org.eclipse.ui.texteditor.ITextEditor;
|
|||
* dispatch thread to synchronize access to the state data of the running jobs.
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class DsfSourceDisplayAdapter implements ISourceDisplay
|
||||
public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControlParticipant
|
||||
{
|
||||
/**
|
||||
* A job to perform source lookup on the given DMC.
|
||||
|
@ -412,8 +416,16 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
|
|||
private DisplayJob fPendingDisplayJob;
|
||||
private ClearingJob fRunningClearingJob;
|
||||
private List<IRunControl.IExecutionDMContext> fPendingExecDmcsToClear = new LinkedList<IRunControl.IExecutionDMContext>();
|
||||
|
||||
private SteppingController fController;
|
||||
|
||||
public DsfSourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator) {
|
||||
this(session, sourceLocator, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
public DsfSourceDisplayAdapter(DsfSession session, ISourceLookupDirector sourceLocator, SteppingController controller) {
|
||||
fSession = session;
|
||||
fExecutor = session.getExecutor();
|
||||
fServicesTracker = new DsfServicesTracker(DsfDebugUIPlugin.getBundleContext(), session.getId());
|
||||
|
@ -424,9 +436,18 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
|
|||
fIPManager = new InstructionPointerManager();
|
||||
|
||||
fSession.addServiceEventListener(this, null);
|
||||
|
||||
fController = controller;
|
||||
if (fController != null) {
|
||||
fController.addSteppingControlParticipant(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (fController != null) {
|
||||
fController.removeSteppingControlParticipant(this);
|
||||
fController = null;
|
||||
}
|
||||
fSession.removeServiceEventListener(this);
|
||||
fServicesTracker.dispose();
|
||||
fSourceLookup.removeParticipants(new ISourceLookupParticipant[] {fSourceLookupParticipant});
|
||||
|
@ -470,7 +491,9 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
|
|||
private void startLookupJob(final IDMContext dmc, final IWorkbenchPage page) {
|
||||
// If there is a previous lookup job running, cancel it.
|
||||
if (fRunningLookupJob != null) {
|
||||
fRunningLookupJob.cancel();
|
||||
if (fRunningLookupJob.cancel()) {
|
||||
doneSourceLookup(fRunningLookupJob.getDmc());
|
||||
}
|
||||
}
|
||||
|
||||
fRunningLookupJob = new LookupJob(dmc, page);
|
||||
|
@ -500,8 +523,22 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
|
|||
fRunningDisplayJob = nextDisplayJob;
|
||||
fRunningDisplayJob.schedule();
|
||||
}
|
||||
doneSourceLookup(lookupResult.getDmc());
|
||||
}
|
||||
|
||||
private void doneSourceLookup(IDMContext context) {
|
||||
if (fController != null) {
|
||||
// indicate completion of step
|
||||
final IExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
|
||||
if (dmc != null) {
|
||||
fController.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
fController.doneStepping(dmc, DsfSourceDisplayAdapter.this);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void serviceDisplayAndClearingJobs() {
|
||||
if (!fPendingExecDmcsToClear.isEmpty()) {
|
||||
|
@ -557,16 +594,18 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay
|
|||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(SteppingTimedOutEvent e) {
|
||||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(StepQueueManager.ISteppingTimedOutEvent e) {
|
||||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
|
||||
if (e.getReason() == StateChangeReason.STEP) {
|
||||
startAnnotationClearingJob(e.getDMContext());
|
||||
}
|
||||
fPrevModelContext = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.jface.text.Position;
|
||||
|
@ -37,7 +38,17 @@ import org.eclipse.ui.texteditor.ITextEditor;
|
|||
@ThreadSafe
|
||||
class InstructionPointerManager {
|
||||
|
||||
/**
|
||||
* Current instruction pointer annotation type.
|
||||
*/
|
||||
private static final String ID_CURRENT_IP= "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Secondary instruction pointer annotation type.
|
||||
*/
|
||||
private static final String ID_SECONDARY_IP= "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Editor annotation object for instruction pointers.
|
||||
*/
|
||||
static class IPAnnotation extends Annotation {
|
||||
|
@ -61,7 +72,7 @@ class InstructionPointerManager {
|
|||
fFrame = frame;
|
||||
fImage = image;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns this annotation's image.
|
||||
*
|
||||
|
@ -170,15 +181,19 @@ class InstructionPointerManager {
|
|||
String text;
|
||||
Image image;
|
||||
if (isTopFrame) {
|
||||
id = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
|
||||
id = ID_CURRENT_IP;
|
||||
text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
|
||||
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
|
||||
} else {
|
||||
id = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
|
||||
id = ID_SECONDARY_IP;
|
||||
text = "Debug Call Stack"; //$NON-NLS-1$
|
||||
image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
|
||||
}
|
||||
|
||||
if (isTopFrame) {
|
||||
// remove other top-frame IP annotation(s) for this execution-context
|
||||
removeAnnotations(DMContexts.getAncestorOfType(frame.getParents()[0], IExecutionDMContext.class));
|
||||
}
|
||||
Annotation annotation = new IPAnnotation(frame, id, text, image);
|
||||
|
||||
// Add the annotation at the position to the editor's annotation model.
|
||||
|
@ -202,10 +217,28 @@ class InstructionPointerManager {
|
|||
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
|
||||
wrapperItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove all top-frame annotations associated with the specified debug target that this class
|
||||
* is tracking.
|
||||
*/
|
||||
public void removeTopFrameAnnotations(IRunControl.IExecutionDMContext execDmc) {
|
||||
// Retrieve the mapping of threads to context lists
|
||||
synchronized(fAnnotationWrappers) {
|
||||
for (Iterator<AnnotationWrapper> wrapperItr = fAnnotationWrappers.iterator(); wrapperItr.hasNext();) {
|
||||
AnnotationWrapper wrapper = wrapperItr.next();
|
||||
if (DMContexts.isAncestorOf(wrapper.getFrameDMC(), execDmc)
|
||||
&& ID_CURRENT_IP.equals(wrapper.getAnnotation().getType())) {
|
||||
removeAnnotation(wrapper.getTextEditor(), wrapper.getAnnotation());
|
||||
wrapperItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes all annotations tracked by this manager */
|
||||
public void removeAllAnnotations() {
|
||||
synchronized(fAnnotationWrappers) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.service;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
|
||||
/**
|
||||
* @since 1.1
|
||||
*/
|
||||
@ConfinedToDsfExecutor("getSession().getExecutor()")
|
||||
public interface IStepQueueManager {
|
||||
|
||||
/**
|
||||
* Returns the session for which this step queue manager is used.
|
||||
*/
|
||||
public DsfSession getSession();
|
||||
|
||||
/**
|
||||
* Checks whether a step command can be queued up for given context.
|
||||
*/
|
||||
public abstract void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm);
|
||||
|
||||
/**
|
||||
* Adds a step command to the execution queue for given context.
|
||||
* @param execCtx Execution context that should perform the step.
|
||||
* @param stepType Type of step to execute.
|
||||
*/
|
||||
public abstract void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType);
|
||||
|
||||
}
|
|
@ -41,11 +41,14 @@ import org.osgi.framework.BundleContext;
|
|||
* is used, other service implementations, such as stack and expressions, can
|
||||
* use it to avoid requesting data from debugger back end if another step is
|
||||
* about to be executed.
|
||||
*
|
||||
* @deprecated The functionality has been integrated in the UI layer.
|
||||
*/
|
||||
public class StepQueueManager extends AbstractDsfService
|
||||
@Deprecated
|
||||
public class StepQueueManager extends AbstractDsfService implements IStepQueueManager
|
||||
{
|
||||
/**
|
||||
* Amount of time in miliseconds, that it takes the ISteppingTimedOutEvent
|
||||
* Amount of time in milliseconds, that it takes the ISteppingTimedOutEvent
|
||||
* event to be issued after a step is started.
|
||||
* @see ISteppingTimedOutEvent
|
||||
*/
|
||||
|
@ -113,9 +116,9 @@ public class StepQueueManager extends AbstractDsfService
|
|||
return DsfDebugPlugin.getBundleContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a step command can be queued up for given context.
|
||||
*/
|
||||
/*
|
||||
* @see org.eclipse.dd.dsf.debug.service.IStepQueueManager#canEnqueueStep(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IRunControl.StepType, org.eclipse.dd.dsf.concurrent.DataRequestMonitor)
|
||||
*/
|
||||
public void canEnqueueStep(IExecutionDMContext execCtx, StepType stepType, DataRequestMonitor<Boolean> rm) {
|
||||
if (doCanEnqueueStep(execCtx, stepType)) {
|
||||
rm.setData(true);
|
||||
|
@ -139,11 +142,9 @@ public class StepQueueManager extends AbstractDsfService
|
|||
return stepQueue.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a step command to the execution queue for given context.
|
||||
* @param execCtx Execution context that should perform the step.
|
||||
* @param stepType Type of step to execute.
|
||||
*/
|
||||
/*
|
||||
* @see org.eclipse.dd.dsf.debug.service.IStepQueueManager#enqueueStep(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IRunControl.StepType)
|
||||
*/
|
||||
public void enqueueStep(final IExecutionDMContext execCtx, final StepType stepType) {
|
||||
fRunControl.canStep(
|
||||
execCtx, stepType, new DataRequestMonitor<Boolean>(getExecutor(), null) {
|
||||
|
|
|
@ -10,14 +10,20 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
|
@ -28,6 +34,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
|
|||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* Base implementation for View Model Adapters. The implementation uses
|
||||
|
@ -38,10 +45,140 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
|
|||
@SuppressWarnings("restriction")
|
||||
abstract public class AbstractVMAdapter implements IVMAdapter
|
||||
{
|
||||
private boolean fDisposed;
|
||||
|
||||
/**
|
||||
* Interface for a viewer update which can be "monitored".
|
||||
*/
|
||||
interface IMonitoredUpdate extends IViewerUpdate {
|
||||
boolean isDone();
|
||||
void setMonitor(RequestMonitor monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an IViewerUpdate to add a request monitor.
|
||||
*/
|
||||
abstract static class MonitoredUpdate implements IMonitoredUpdate {
|
||||
|
||||
protected IViewerUpdate fDelegate;
|
||||
private boolean fIsDone;
|
||||
private RequestMonitor fMonitor;
|
||||
|
||||
MonitoredUpdate(IViewerUpdate update) {
|
||||
fDelegate = update;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return fIsDone;
|
||||
}
|
||||
|
||||
public void setMonitor(RequestMonitor monitor) {
|
||||
fMonitor = monitor;
|
||||
if (fIsDone) {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
public Object getElement() {
|
||||
return fDelegate.getElement();
|
||||
}
|
||||
|
||||
public TreePath getElementPath() {
|
||||
return fDelegate.getElementPath();
|
||||
}
|
||||
|
||||
public IPresentationContext getPresentationContext() {
|
||||
return fDelegate.getPresentationContext();
|
||||
}
|
||||
|
||||
public Object getViewerInput() {
|
||||
return fDelegate.getViewerInput();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
fDelegate.cancel();
|
||||
if (!fIsDone) {
|
||||
fIsDone = true;
|
||||
if (fMonitor != null) {
|
||||
fMonitor.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void done() {
|
||||
fDelegate.done();
|
||||
if (!fIsDone) {
|
||||
fIsDone = true;
|
||||
if (fMonitor != null) {
|
||||
fMonitor.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IStatus getStatus() {
|
||||
return fDelegate.getStatus();
|
||||
}
|
||||
|
||||
public boolean isCanceled() {
|
||||
return fDelegate.isCanceled();
|
||||
}
|
||||
|
||||
public void setStatus(IStatus status) {
|
||||
fDelegate.setStatus(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MonitoredChildrenUpdate extends MonitoredUpdate implements IChildrenUpdate {
|
||||
public MonitoredChildrenUpdate(IChildrenUpdate update) {
|
||||
super(update);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return ((IChildrenUpdate)fDelegate).getLength();
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return ((IChildrenUpdate)fDelegate).getOffset();
|
||||
}
|
||||
|
||||
public void setChild(Object child, int offset) {
|
||||
((IChildrenUpdate)fDelegate).setChild(child, offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MonitoredHasChildrenUpdate extends MonitoredUpdate implements IHasChildrenUpdate {
|
||||
public MonitoredHasChildrenUpdate(IHasChildrenUpdate update) {
|
||||
super(update);
|
||||
}
|
||||
|
||||
public void setHasChilren(boolean hasChildren) {
|
||||
((IHasChildrenUpdate)fDelegate).setHasChilren(hasChildren);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MonitoredChildrenCountUpdate extends MonitoredUpdate implements IChildrenCountUpdate {
|
||||
public MonitoredChildrenCountUpdate(IChildrenCountUpdate update) {
|
||||
super(update);
|
||||
}
|
||||
|
||||
public void setChildCount(int numChildren) {
|
||||
((IChildrenCountUpdate)fDelegate).setChildCount(numChildren);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private boolean fDisposed;
|
||||
|
||||
private final Map<IPresentationContext, IVMProvider> fViewModelProviders =
|
||||
Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() );
|
||||
Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() );
|
||||
|
||||
/**
|
||||
* List of IViewerUpdates pending after processing an event.
|
||||
*/
|
||||
private final List<IMonitoredUpdate> fPendingUpdates = new ArrayList<IMonitoredUpdate>();
|
||||
|
||||
/**
|
||||
* Constructor for the View Model session. It is tempting to have the
|
||||
|
@ -70,6 +207,16 @@ abstract public class AbstractVMAdapter implements IVMAdapter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate the VM providers.
|
||||
* @return An instance of {@link Iterable<IVMProvider>}
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected Iterable<IVMProvider> getVMProviderIterable() {
|
||||
return fViewModelProviders.values();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
IVMProvider[] providers = new IVMProvider[0];
|
||||
synchronized(fViewModelProviders) {
|
||||
|
@ -91,31 +238,29 @@ abstract public class AbstractVMAdapter implements IVMAdapter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this VM adapter is disposed.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public boolean isDisposed() {
|
||||
return fDisposed;
|
||||
}
|
||||
|
||||
public void update(IHasChildrenUpdate[] updates) {
|
||||
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
|
||||
if (provider != null) {
|
||||
updateProvider(provider, updates);
|
||||
} else {
|
||||
for (IViewerUpdate update : updates) {
|
||||
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
|
||||
"No model provider for update " + update, null)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
handleUpdate(updates);
|
||||
}
|
||||
|
||||
public void update(IChildrenCountUpdate[] updates) {
|
||||
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
|
||||
if (provider != null) {
|
||||
updateProvider(provider, updates);
|
||||
} else {
|
||||
for (IViewerUpdate update : updates) {
|
||||
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
|
||||
"No model provider for update " + update, null)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
handleUpdate(updates);
|
||||
}
|
||||
|
||||
public void update(final IChildrenUpdate[] updates) {
|
||||
handleUpdate(updates);
|
||||
}
|
||||
|
||||
private void handleUpdate(IViewerUpdate[] updates) {
|
||||
updates = wrapUpdates(updates);
|
||||
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
|
||||
if (provider != null) {
|
||||
updateProvider(provider, updates);
|
||||
|
@ -123,10 +268,11 @@ abstract public class AbstractVMAdapter implements IVMAdapter
|
|||
for (IViewerUpdate update : updates) {
|
||||
update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
|
||||
"No model provider for update " + update, null)); //$NON-NLS-1$
|
||||
update.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateProvider(final IVMProvider provider, final IViewerUpdate[] updates) {
|
||||
try {
|
||||
provider.getExecutor().execute(new Runnable() {
|
||||
|
@ -187,4 +333,110 @@ abstract public class AbstractVMAdapter implements IVMAdapter
|
|||
*/
|
||||
@ThreadSafe
|
||||
abstract protected IVMProvider createViewModelProvider(IPresentationContext context);
|
||||
|
||||
/**
|
||||
* Dispatch given event to VM providers interested in events.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected final void handleEvent(final Object event) {
|
||||
final List<IVMEventListener> eventListeners = new ArrayList<IVMEventListener>();
|
||||
|
||||
aboutToHandleEvent(event);
|
||||
|
||||
for (IVMProvider vmProvider : getVMProviderIterable()) {
|
||||
if (vmProvider instanceof IVMEventListener) {
|
||||
eventListeners.add((IVMEventListener)vmProvider);
|
||||
}
|
||||
}
|
||||
|
||||
if (!eventListeners.isEmpty()) {
|
||||
synchronized (fPendingUpdates) {
|
||||
fPendingUpdates.clear();
|
||||
}
|
||||
// TODO which executor to use?
|
||||
final Executor executor= eventListeners.get(0).getExecutor();
|
||||
final CountingRequestMonitor crm = new CountingRequestMonitor(executor, null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
// The event listeners have completed processing the event.
|
||||
// Now monitor completion of viewer updates issued while dispatching the event
|
||||
final CountingRequestMonitor updatesMonitor = new CountingRequestMonitor(executor, null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
doneHandleEvent(event);
|
||||
}
|
||||
};
|
||||
synchronized (fPendingUpdates) {
|
||||
int pending = fPendingUpdates.size();
|
||||
updatesMonitor.setDoneCount(pending);
|
||||
for (IMonitoredUpdate update : fPendingUpdates) {
|
||||
update.setMonitor(updatesMonitor);
|
||||
}
|
||||
fPendingUpdates.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
crm.setDoneCount(eventListeners.size());
|
||||
|
||||
for (final IVMEventListener vmEventListener : eventListeners) {
|
||||
vmEventListener.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
vmEventListener.handleEvent(event, crm);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IViewerUpdate[] wrapUpdates(IViewerUpdate[] updates) {
|
||||
if (updates.length == 0) {
|
||||
return updates;
|
||||
}
|
||||
int i = 0;
|
||||
synchronized (fPendingUpdates) {
|
||||
for (IViewerUpdate update : updates) {
|
||||
IMonitoredUpdate wrap= createMonitoredUpdate(update);
|
||||
updates[i++] = wrap;
|
||||
fPendingUpdates.add(wrap);
|
||||
}
|
||||
}
|
||||
return updates;
|
||||
}
|
||||
|
||||
private IMonitoredUpdate createMonitoredUpdate(IViewerUpdate update) {
|
||||
if (update instanceof IChildrenCountUpdate) {
|
||||
return new MonitoredChildrenCountUpdate(((IChildrenCountUpdate)update));
|
||||
} else if (update instanceof IHasChildrenUpdate) {
|
||||
return new MonitoredHasChildrenUpdate(((IHasChildrenUpdate)update));
|
||||
} else if (update instanceof IChildrenUpdate) {
|
||||
return new MonitoredChildrenUpdate(((IChildrenUpdate)update));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given event is about to be handled.
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected void aboutToHandleEvent(final Object event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given event has been processed by all VM event listeners.
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected void doneHandleEvent(final Object event) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
|
@ -60,7 +61,7 @@ import org.eclipse.swt.widgets.Display;
|
|||
* @see IVMNode
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
abstract public class AbstractVMProvider implements IVMProvider
|
||||
abstract public class AbstractVMProvider implements IVMProvider, IVMEventListener
|
||||
{
|
||||
|
||||
/** Reference to the VM adapter that owns this provider */
|
||||
|
@ -204,8 +205,20 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
* Processes the given event in the given provider, sending model
|
||||
* deltas if necessary.
|
||||
*/
|
||||
public void handleEvent(final Object event) {
|
||||
for (final IVMModelProxy proxyStrategy : getActiveModelProxies()) {
|
||||
public void handleEvent(final Object event) {
|
||||
handleEvent(event, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.1
|
||||
*/
|
||||
public void handleEvent(final Object event, RequestMonitor rm) {
|
||||
CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
|
||||
final List<IVMModelProxy> activeModelProxies= new ArrayList<IVMModelProxy>(getActiveModelProxies());
|
||||
crm.setDoneCount(activeModelProxies.size());
|
||||
|
||||
for (final IVMModelProxy proxyStrategy : activeModelProxies) {
|
||||
if (proxyStrategy.isDeltaEvent(event)) {
|
||||
if (!fEventQueues.containsKey(proxyStrategy)) {
|
||||
fEventQueues.put(proxyStrategy, new ModelProxyEventQueue());
|
||||
|
@ -222,13 +235,16 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
}
|
||||
}
|
||||
}
|
||||
crm.done();
|
||||
queue.fEventQueue.add(event);
|
||||
} else {
|
||||
doHandleEvent(queue, proxyStrategy, event);
|
||||
doHandleEvent(queue, proxyStrategy, event, crm);
|
||||
}
|
||||
} else {
|
||||
crm.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clean up model proxies that were removed.
|
||||
List<IVMModelProxy> activeProxies = getActiveModelProxies();
|
||||
for (Iterator<IVMModelProxy> itr = fEventQueues.keySet().iterator(); itr.hasNext();) {
|
||||
|
@ -237,8 +253,8 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event) {
|
||||
|
||||
private void doHandleEvent(final ModelProxyEventQueue queue, final IVMModelProxy proxyStrategy, final Object event, final RequestMonitor rm) {
|
||||
queue.fProcessingEvent = true;
|
||||
handleEvent(
|
||||
proxyStrategy, event,
|
||||
|
@ -247,8 +263,10 @@ abstract public class AbstractVMProvider implements IVMProvider
|
|||
protected void handleCompleted() {
|
||||
queue.fProcessingEvent = false;
|
||||
if (!queue.fEventQueue.isEmpty()) {
|
||||
doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0));
|
||||
}
|
||||
doHandleEvent(queue, proxyStrategy, queue.fEventQueue.remove(0), rm);
|
||||
} else {
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
|
||||
/**
|
||||
* A listener participating in event notifications sent out from VM adapter.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public interface IVMEventListener {
|
||||
|
||||
/**
|
||||
* Returns the executor that needs to be used to access this event listener.
|
||||
*/
|
||||
public Executor getExecutor();
|
||||
|
||||
/**
|
||||
* Process the given event and indicate completion with request monitor.
|
||||
*/
|
||||
public abstract void handleEvent(final Object event, RequestMonitor rm);
|
||||
}
|
|
@ -200,6 +200,8 @@ public class VMDelta extends ModelDelta {
|
|||
*
|
||||
* @param element child element
|
||||
* @return corresponding delta node, or <code>null</code>
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@Override
|
||||
public VMDelta getChildDelta(Object element) {
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel.datamodel;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
|
||||
|
@ -22,6 +26,13 @@ abstract public class AbstractDMVMAdapter extends AbstractVMAdapter
|
|||
{
|
||||
private final DsfSession fSession;
|
||||
|
||||
/**
|
||||
* It is theoretically possible for a VM adapter to be disposed before it
|
||||
* has a chance to register itself as event listener. This flag is used
|
||||
* to avoid removing itself as listener in such situation.
|
||||
*/
|
||||
private boolean fRegisteredAsEventListener = false;
|
||||
|
||||
/**
|
||||
* Constructor for the View Model session. It is tempting to have the
|
||||
* adapter register itself here with the session as the model adapter, but
|
||||
|
@ -33,12 +44,59 @@ abstract public class AbstractDMVMAdapter extends AbstractVMAdapter
|
|||
public AbstractDMVMAdapter(DsfSession session) {
|
||||
super();
|
||||
fSession = session;
|
||||
// Add ourselves as listener for DM events events.
|
||||
try {
|
||||
session.getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
if (DsfSession.isSessionActive(getSession().getId())) {
|
||||
getSession().addServiceEventListener(AbstractDMVMAdapter.this, null);
|
||||
fRegisteredAsEventListener = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Session shut down, not much we can do but wait to be disposed.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
getSession().getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
if (fRegisteredAsEventListener && getSession().isActive()) {
|
||||
fSession.removeServiceEventListener(AbstractDMVMAdapter.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Session shut down.
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DSF session that this adapter is associated with.
|
||||
* @return
|
||||
*/
|
||||
protected DsfSession getSession() { return fSession; }
|
||||
|
||||
/**
|
||||
* Handle "data model changed" event by generating a delta object for each
|
||||
* view and passing it to the corresponding view model provider. The view
|
||||
* model provider is then responsible for filling-in and sending the delta
|
||||
* to the viewer.
|
||||
*
|
||||
* @param event
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
public final void eventDispatched(final IDMEvent<?> event) {
|
||||
// We're in session's executor thread (session in which the event originated).
|
||||
if (isDisposed()) return;
|
||||
|
||||
handleEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.ui.viewmodel.datamodel;
|
||||
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||
|
@ -44,14 +42,6 @@ import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapt
|
|||
abstract public class AbstractDMVMProvider extends AbstractCachingVMProvider
|
||||
{
|
||||
private final DsfSession fSession;
|
||||
|
||||
/**
|
||||
* It is theoretically possible for a VMProvider to be disposed before it
|
||||
* has a chance to register itself as event listener. This flag is used
|
||||
* to avoid removing itself as listener in such situation.
|
||||
*/
|
||||
private boolean fRegisteredAsEventListener = false;
|
||||
|
||||
/**
|
||||
* Constructs the view model provider for given DSF session. The
|
||||
* constructor is thread-safe to allow VM provider to be constructed
|
||||
|
@ -61,64 +51,16 @@ abstract public class AbstractDMVMProvider extends AbstractCachingVMProvider
|
|||
public AbstractDMVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, DsfSession session) {
|
||||
super(adapter, presentationContext);
|
||||
fSession = session;
|
||||
// Add ourselves as listener for DM events events.
|
||||
try {
|
||||
session.getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
if (DsfSession.isSessionActive(getSession().getId())) {
|
||||
getSession().addServiceEventListener(AbstractDMVMProvider.this, null);
|
||||
fRegisteredAsEventListener = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Session shut down, not much we can do but wait to be disposed.
|
||||
}
|
||||
}
|
||||
|
||||
/** Called to dispose the provider. */
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
getSession().getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
if (DsfSession.isSessionActive(getSession().getId()) && fRegisteredAsEventListener ) {
|
||||
fSession.removeServiceEventListener(AbstractDMVMProvider.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Session shut down.
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public DsfSession getSession() { return fSession; }
|
||||
|
||||
/**
|
||||
* Handle "data model changed" event by generating a delta object for each
|
||||
* view and passing it to the corresponding view model provider. The view
|
||||
* model provider is then responsible for filling-in and sending the delta
|
||||
* to the viewer.
|
||||
* @param e
|
||||
* @deprecated Kept for API compatibility reasons.
|
||||
* Events are now received and dispatched by the VM adapter.
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
@Deprecated
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final IDMEvent<?> event) {
|
||||
// We're in session's executor thread (session in which the event originated).
|
||||
// Re-dispach to the view model provider executor thread and then call the
|
||||
// model proxy strategy to handle the event.
|
||||
if (isDisposed()) return;
|
||||
|
||||
try {
|
||||
getExecutor().execute(new Runnable() {
|
||||
public void run() {
|
||||
if (isDisposed()) return;
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
} catch (RejectedExecutionException e) {
|
||||
// Ignore. This exception could be thrown if the provider is being
|
||||
// shut down.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Map;
|
|||
import org.eclipse.core.runtime.IAdapterFactory;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory;
|
||||
import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
|
||||
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
|
||||
|
@ -62,7 +63,7 @@ import org.eclipse.debug.ui.sourcelookup.ISourceDisplay;
|
|||
public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
|
||||
{
|
||||
/**
|
||||
* Contains the set of adapters that are created for eacy launch instance.
|
||||
* Contains the set of adapters that are created for each launch instance.
|
||||
*/
|
||||
@Immutable
|
||||
private static class LaunchAdapterSet {
|
||||
|
@ -84,6 +85,8 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
|
|||
final IDebugModelProvider fDebugModelProvider;
|
||||
final PDALaunch fLaunch;
|
||||
|
||||
final SteppingController fSteppingController;
|
||||
|
||||
private IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
|
||||
|
||||
LaunchAdapterSet(PDALaunch launch) {
|
||||
|
@ -91,11 +94,15 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
|
|||
fLaunch = launch;
|
||||
DsfSession session = launch.getSession();
|
||||
|
||||
// register stepping controller
|
||||
fSteppingController = new SteppingController(session);
|
||||
session.registerModelAdapter(SteppingController.class, fSteppingController);
|
||||
|
||||
// Initialize VM
|
||||
fViewModelAdapter = new PDAVMAdapter(session);
|
||||
fViewModelAdapter = new PDAVMAdapter(session, fSteppingController);
|
||||
|
||||
// Initialize source lookup
|
||||
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
|
||||
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
|
||||
session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter);
|
||||
|
||||
// Default selection policy
|
||||
|
@ -128,7 +135,7 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
|
|||
// and debug model ID will be associated with all DMContexts from this
|
||||
// session.
|
||||
session.registerModelAdapter(ILaunch.class, fLaunch);
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
DsfSession session = fLaunch.getSession();
|
||||
|
@ -138,6 +145,9 @@ public class PDAAdapterFactory implements IAdapterFactory, ILaunchesListener2
|
|||
session.unregisterModelAdapter(ISourceDisplay.class);
|
||||
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
|
||||
|
||||
session.unregisterModelAdapter(SteppingController.class);
|
||||
fSteppingController.dispose();
|
||||
|
||||
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
|
||||
|
||||
session.unregisterModelAdapter(IStepIntoHandler.class);
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
package org.eclipse.dd.examples.pda.ui.viewmodel;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.AbstractDebugVMAdapter;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.dd.examples.pda.ui.viewmodel.launch.PDALaunchVMProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
|
||||
|
@ -24,10 +25,10 @@ import org.eclipse.debug.ui.IDebugUIConstants;
|
|||
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("restriction")
|
||||
public class PDAVMAdapter extends AbstractDMVMAdapter
|
||||
public class PDAVMAdapter extends AbstractDebugVMAdapter
|
||||
{
|
||||
public PDAVMAdapter(DsfSession session) {
|
||||
super(session);
|
||||
public PDAVMAdapter(DsfSession session, SteppingController controller) {
|
||||
super(session, controller);
|
||||
getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.eclipse.dd.examples.pda.launch;
|
|||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||
import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.examples.pda.service.PDABreakpointAttributeTranslator;
|
||||
import org.eclipse.dd.examples.pda.service.PDABreakpoints;
|
||||
|
@ -54,13 +53,6 @@ public class PDAServicesInitSequence extends Sequence {
|
|||
fRunControl.initialize(requestMonitor);
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
// Start the service to manage step actions.
|
||||
new StepQueueManager(fSession).initialize(requestMonitor);
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
|
|
|
@ -17,7 +17,6 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
|||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||
import org.eclipse.dd.dsf.debug.service.BreakpointsMediator;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.dd.examples.pda.PDAPlugin;
|
||||
|
@ -86,12 +85,6 @@ public class PDAServicesShutdownSequence extends Sequence {
|
|||
shutdownService(PDABreakpoints.class, requestMonitor);
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
shutdownService(StepQueueManager.class, requestMonitor);
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
|
|||
import org.eclipse.core.runtime.IAdapterFactory;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.DefaultDsfModelSelectionPolicyFactory;
|
||||
import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand;
|
||||
import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand;
|
||||
|
@ -79,15 +80,20 @@ public class GdbAdapterFactory
|
|||
final DsfSuspendTrigger fSuspendTrigger;
|
||||
final DsfSteppingModeTarget fSteppingModeTarget;
|
||||
final IModelSelectionPolicyFactory fModelSelectionPolicyFactory;
|
||||
final SteppingController fSteppingController;
|
||||
|
||||
SessionAdapterSet(GdbLaunch launch) {
|
||||
fLaunch = launch;
|
||||
DsfSession session = launch.getSession();
|
||||
|
||||
fViewModelAdapter = new GdbViewModelAdapter(session);
|
||||
// register stepping controller
|
||||
fSteppingController = new SteppingController(session);
|
||||
session.registerModelAdapter(SteppingController.class, fSteppingController);
|
||||
|
||||
fViewModelAdapter = new GdbViewModelAdapter(session, fSteppingController);
|
||||
|
||||
if (launch.getSourceLocator() instanceof ISourceLookupDirector) {
|
||||
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator());
|
||||
fSourceDisplayAdapter = new DsfSourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator(), fSteppingController);
|
||||
} else {
|
||||
fSourceDisplayAdapter = null;
|
||||
}
|
||||
|
@ -137,7 +143,10 @@ public class GdbAdapterFactory
|
|||
|
||||
session.unregisterModelAdapter(ISourceDisplay.class);
|
||||
if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose();
|
||||
|
||||
|
||||
session.unregisterModelAdapter(SteppingController.class);
|
||||
fSteppingController.dispose();
|
||||
|
||||
session.unregisterModelAdapter(ISteppingModeTarget.class);
|
||||
session.unregisterModelAdapter(IStepIntoHandler.class);
|
||||
session.unregisterModelAdapter(IStepOverHandler.class);
|
||||
|
@ -147,7 +156,7 @@ public class GdbAdapterFactory
|
|||
session.unregisterModelAdapter(IRestart.class);
|
||||
session.unregisterModelAdapter(ITerminateHandler.class);
|
||||
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
|
||||
|
||||
|
||||
fStepIntoCommand.dispose();
|
||||
fStepOverCommand.dispose();
|
||||
fStepReturnCommand.dispose();
|
||||
|
|
|
@ -11,12 +11,13 @@
|
|||
package org.eclipse.dd.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.AbstractDebugVMAdapter;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.SteppingController;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.expression.ExpressionVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.modules.ModulesVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.register.RegisterVMProvider;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMAdapter;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.dd.gdb.internal.ui.viewmodel.launch.LaunchVMProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
|
||||
|
@ -28,10 +29,10 @@ import org.eclipse.debug.ui.IDebugUIConstants;
|
|||
*/
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("restriction")
|
||||
public class GdbViewModelAdapter extends AbstractDMVMAdapter
|
||||
public class GdbViewModelAdapter extends AbstractDebugVMAdapter
|
||||
{
|
||||
public GdbViewModelAdapter(DsfSession session) {
|
||||
super(session);
|
||||
public GdbViewModelAdapter(DsfSession session, SteppingController controller) {
|
||||
super(session, controller);
|
||||
getSession().registerModelAdapter(IColumnPresentationFactory.class, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.eclipse.dd.dsf.debug.service.IRegisters;
|
|||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.ISourceLookup;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
|
||||
|
@ -55,10 +54,6 @@ public class ServicesLaunchSequence extends Sequence {
|
|||
fLaunch.getServiceFactory().createService(fSession, IProcesses.class).initialize(requestMonitor);
|
||||
}},
|
||||
new Step() { @Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
new StepQueueManager(fSession).initialize(requestMonitor);
|
||||
}},
|
||||
new Step() { @Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
fLaunch.getServiceFactory().createService(fSession, IMemory.class).initialize(requestMonitor);
|
||||
}},
|
||||
|
|
Loading…
Add table
Reference in a new issue