From 337235a75e44c41c46e0f94129d2c9ceea3f9984 Mon Sep 17 00:00:00 2001
From: Anton Leherbauer
Date: Wed, 16 Jul 2008 11:02:58 +0000
Subject: [PATCH] 214386: [run control][debug view][source lookup] When
stepping fast (holding down F5 key) the IP in editor does not keep up.
---
.../ui/viewmodel/AbstractDebugVMAdapter.java | 65 ++
.../ui/viewmodel/SteppingController.java | 593 ++++++++++++++++++
.../launch/AbstractContainerVMNode.java | 17 +
.../launch/AbstractLaunchVMProvider.java | 49 +-
.../launch/AbstractThreadVMNode.java | 20 +
.../DelayedStackRefreshUpdatePolicy.java | 2 +
.../ui/viewmodel/launch/ExpandStackEvent.java | 2 +
.../launch/FullStackRefreshEvent.java | 2 +
.../launch/LaunchVMUpdateMessages.java | 3 +
.../viewmodel/launch/StackFramesVMNode.java | 37 +-
.../preferences/DsfDebugPreferencePage.java | 55 +-
.../IntegerWithBooleanFieldEditor.java | 38 +-
.../preferences/MessagesForPreferences.java | 4 +
.../StringWithBooleanFieldEditor.java | 38 +-
.../ui/preferences/messages.properties | 2 +
.../dd/dsf/debug/ui/IDsfDebugUIConstants.java | 27 +-
.../dsf/debug/ui/PreferenceInitializer.java | 4 +-
.../debug/ui/actions/DsfCommandRunnable.java | 32 +-
.../debug/ui/actions/DsfStepIntoCommand.java | 4 +-
.../debug/ui/actions/DsfStepOverCommand.java | 4 +-
.../ui/actions/DsfStepReturnCommand.java | 4 +-
.../sourcelookup/DsfSourceDisplayAdapter.java | 53 +-
.../InstructionPointerManager.java | 43 +-
.../dsf/debug/service/IStepQueueManager.java | 42 ++
.../dsf/debug/service/StepQueueManager.java | 21 +-
.../dsf/ui/viewmodel/AbstractVMAdapter.java | 294 ++++++++-
.../dsf/ui/viewmodel/AbstractVMProvider.java | 36 +-
.../dd/dsf/ui/viewmodel/IVMEventListener.java | 33 +
.../eclipse/dd/dsf/ui/viewmodel/VMDelta.java | 2 +
.../datamodel/AbstractDMVMAdapter.java | 58 ++
.../datamodel/AbstractDMVMProvider.java | 66 +-
.../dd/examples/pda/ui/PDAAdapterFactory.java | 18 +-
.../pda/ui/viewmodel/PDAVMAdapter.java | 9 +-
.../pda/launch/PDAServicesInitSequence.java | 8 -
.../launch/PDAServicesShutdownSequence.java | 7 -
.../dd/gdb/internal/ui/GdbAdapterFactory.java | 17 +-
.../ui/viewmodel/GdbViewModelAdapter.java | 9 +-
.../launching/ServicesLaunchSequence.java | 5 -
38 files changed, 1494 insertions(+), 229 deletions(-)
create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/AbstractDebugVMAdapter.java
create mode 100644 plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/SteppingController.java
create mode 100644 plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java
create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMEventListener.java
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/AbstractDebugVMAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/AbstractDebugVMAdapter.java
new file mode 100644
index 00000000000..75a5fea790c
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/AbstractDebugVMAdapter.java
@@ -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();
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/SteppingController.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/SteppingController.java
new file mode 100644
index 00000000000..52874738ff5
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/SteppingController.java
@@ -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 {
+ 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> fStepQueues = new HashMap>();
+ private final Map fTimedOutFlags = new HashMap();
+ private final Map> fTimedOutFutures = new HashMap>();
+
+ /**
+ * Records the time of the last step for an execution context.
+ */
+ private final Map fLastStepTimes= new HashMap();
+
+ /**
+ * 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> fStepInProgress = new HashMap>();
+
+ /**
+ * List of registered stepping control participants.
+ */
+ private final List fParticipants = Collections.synchronizedList(new ArrayList());
+
+ /**
+ * 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.
+ *
+ * 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.
+ *
+ *
+ * @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 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 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 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 true
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 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(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 stepQueue = fStepQueues.get(execCtx);
+ if (stepQueue == null) {
+ stepQueue = new LinkedList();
+ 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 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(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(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());
+ }
+
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java
index 99ec56d2a9c..38806401c26 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractContainerVMNode.java
@@ -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
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractLaunchVMProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractLaunchVMProvider.java
index 01434430425..91e47fc2efc 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractLaunchVMProvider.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractLaunchVMProvider.java
@@ -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);
+ }
+ });
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java
index 2dc2ccde8eb..4e09c9472f9 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/AbstractThreadVMNode.java
@@ -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
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/DelayedStackRefreshUpdatePolicy.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/DelayedStackRefreshUpdatePolicy.java
index 690b65ba157..31924f4a410 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/DelayedStackRefreshUpdatePolicy.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/DelayedStackRefreshUpdatePolicy.java
@@ -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.
*
+ *
+ * @since 1.1
*/
public class DelayedStackRefreshUpdatePolicy extends UpdatePolicyDecorator {
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/ExpandStackEvent.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/ExpandStackEvent.java
index dbbdb2bd336..2381ed26668 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/ExpandStackEvent.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/ExpandStackEvent.java
@@ -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 {
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/FullStackRefreshEvent.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/FullStackRefreshEvent.java
index 32e567e52b5..5c3a45e6b5f 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/FullStackRefreshEvent.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/FullStackRefreshEvent.java
@@ -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 {
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchVMUpdateMessages.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchVMUpdateMessages.java
index f298c6f3e4f..3c71da2b583 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchVMUpdateMessages.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/LaunchVMUpdateMessages.java
@@ -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$
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java
index 4f2516d8080..ffd83b5f97f 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/provisional/ui/viewmodel/launch/StackFramesVMNode.java
@@ -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);
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/DsfDebugPreferencePage.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/DsfDebugPreferencePage.java
index 68f9fe9a314..4adfb0ca938 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/DsfDebugPreferencePage.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/DsfDebugPreferencePage.java
@@ -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
}
}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/IntegerWithBooleanFieldEditor.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/IntegerWithBooleanFieldEditor.java
index b8d310acd0c..b53cdf1d1e4 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/IntegerWithBooleanFieldEditor.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/IntegerWithBooleanFieldEditor.java
@@ -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) {
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/MessagesForPreferences.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/MessagesForPreferences.java
index b7b791278b9..bd38bb58f43 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/MessagesForPreferences.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/MessagesForPreferences.java
@@ -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);
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/StringWithBooleanFieldEditor.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/StringWithBooleanFieldEditor.java
index 09287a158ab..4f9edd0ae0f 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/StringWithBooleanFieldEditor.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/StringWithBooleanFieldEditor.java
@@ -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) {
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/messages.properties b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/messages.properties
index f92522e6d87..225e6b1fe2d 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/messages.properties
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/preferences/messages.properties
@@ -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
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java
index 4b3b6ab3e2d..57df777d292 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/IDsfDebugUIConstants.java
@@ -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 true
.
* @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 true
.
+ *
+ * @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 0
.
+ *
+ * @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$
}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/PreferenceInitializer.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/PreferenceInitializer.java
index 29eb9fa7021..b5bf689b925 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/PreferenceInitializer.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/PreferenceInitializer.java
@@ -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);
+ }
}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java
index e842d3c91e5..66bcf9dbfdf 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfCommandRunnable.java
@@ -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();
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java
index 5f712988ff6..40e20387800 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepIntoCommand.java
@@ -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(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;
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java
index 3df804ac035..99af9e2236a 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepOverCommand.java
@@ -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(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;
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java
index 2977e3c3195..26871d2b26d 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/actions/DsfStepReturnCommand.java
@@ -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(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;
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java
index ff7dd295931..46e389fe690 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/DsfSourceDisplayAdapter.java
@@ -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 fPendingExecDmcsToClear = new LinkedList();
-
+ 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;
}
}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java
index b549a570101..bd4d19edd29 100644
--- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/sourcelookup/InstructionPointerManager.java
@@ -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 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) {
diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java
new file mode 100644
index 00000000000..30573fd84cc
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IStepQueueManager.java
@@ -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 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);
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java
index 838d865f8cc..a5389516bb7 100644
--- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java
+++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/StepQueueManager.java
@@ -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 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(getExecutor(), null) {
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java
index 91adfafa113..0e07e4d4a20 100644
--- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMAdapter.java
@@ -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 fViewModelProviders =
- Collections.synchronizedMap( new HashMap() );
+ Collections.synchronizedMap( new HashMap() );
+
+ /**
+ * List of IViewerUpdates pending after processing an event.
+ */
+ private final List fPendingUpdates = new ArrayList();
/**
* 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}
+ *
+ * @since 1.1
+ */
+ protected Iterable 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 eventListeners = new ArrayList();
+
+ 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) {
+ }
}
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java
index 9583d04bbb4..eac4f630394 100644
--- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/AbstractVMProvider.java
@@ -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 activeModelProxies= new ArrayList(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 activeProxies = getActiveModelProxies();
for (Iterator 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();
+ }
}
});
}
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMEventListener.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMEventListener.java
new file mode 100644
index 00000000000..9c17198ddd5
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/IVMEventListener.java
@@ -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);
+}
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java
index bfbc375bf1e..1ddd3eba1c9 100644
--- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/VMDelta.java
@@ -200,6 +200,8 @@ public class VMDelta extends ModelDelta {
*
* @param element child element
* @return corresponding delta node, or null
+ *
+ * @since 1.1
*/
@Override
public VMDelta getChildDelta(Object element) {
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java
index cc874a0bed2..e562b8bbba5 100644
--- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMAdapter.java
@@ -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);
+ }
+
}
diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java
index fea7cf1bc92..18e42e1c676 100644
--- a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java
+++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/datamodel/AbstractDMVMProvider.java
@@ -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.
- }
}
}
diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java
index 3315c57a7db..e30d9ba61c2 100644
--- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java
+++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/PDAAdapterFactory.java
@@ -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);
diff --git a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java
index 96b3036a9f5..ae438e09aa4 100644
--- a/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java
+++ b/plugins/org.eclipse.dd.examples.pda.ui/src/org/eclipse/dd/examples/pda/ui/viewmodel/PDAVMAdapter.java
@@ -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);
}
diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java
index 1de0b2aa12f..bbdd44ed625 100644
--- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java
+++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesInitSequence.java
@@ -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) {
diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java
index 43a674abe1c..a5de87e7ac2 100644
--- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java
+++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDAServicesShutdownSequence.java
@@ -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) {
diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java
index 2ea44db1a2d..4114088decd 100644
--- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java
+++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/GdbAdapterFactory.java
@@ -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();
diff --git a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java
index 97d9f828f49..8baa60e6177 100644
--- a/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java
+++ b/plugins/org.eclipse.dd.gdb.ui/src/org/eclipse/dd/gdb/internal/ui/viewmodel/GdbViewModelAdapter.java
@@ -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);
}
diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java
index b6d5a4dfc24..622b1ebf04c 100644
--- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java
+++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/launching/ServicesLaunchSequence.java
@@ -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);
}},