1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-17 05:55:22 +02:00

[246640] - [run control][update policy] Stepping should always be synchronized with painting the IP

This commit is contained in:
Pawel Piech 2008-09-09 21:13:16 +00:00
parent cfe2a71e89
commit 0e70351e3f
20 changed files with 117 additions and 341 deletions

View file

@ -12,7 +12,7 @@ pluginName=Debug Services Framework Debug UI
providerName=Eclipse.org providerName=Eclipse.org
# disassembly # disassembly
disassemblyPreferencePage.name = DSF Disassembly disassemblyPreferencePage.name = Disassembly
disassemblyView.name= DSF Disassembly disassemblyView.name= DSF Disassembly
command.gotoPC.name=Go to Program Counter command.gotoPC.name=Go to Program Counter
@ -51,7 +51,7 @@ action.setDefaultNumberFormatOctal.label = Octal
action.setDefaultNumberFormatBinary.label = Binary action.setDefaultNumberFormatBinary.label = Binary
action.setDefaultNumberFormatNatural.label = Natural action.setDefaultNumberFormatNatural.label = Natural
preferencePage.name = DSF Performance preferencePage.name = DSF
action.expandStack.label = E&xpand Stack action.expandStack.label = E&xpand Stack

View file

@ -527,17 +527,17 @@
<extension <extension
point="org.eclipse.ui.preferencePages"> point="org.eclipse.ui.preferencePages">
<page
class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferencePage"
category="org.eclipse.debug.ui.DebugPreferencePage"
name="%disassemblyPreferencePage.name"
id="org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"/>
<page <page
category="org.eclipse.debug.ui.DebugPreferencePage" category="org.eclipse.debug.ui.DebugPreferencePage"
class="org.eclipse.dd.dsf.debug.internal.ui.preferences.DsfDebugPreferencePage" class="org.eclipse.dd.dsf.debug.internal.ui.preferences.DsfDebugPreferencePage"
id="org.eclipse.dd.dsf.debug.ui.preferences" id="org.eclipse.dd.dsf.debug.ui.preferences"
name="%preferencePage.name"> name="%preferencePage.name">
</page> </page>
<page
class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferencePage"
category="org.eclipse.dd.dsf.debug.ui.preferences"
name="%disassemblyPreferencePage.name"
id="org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"/>
</extension> </extension>
<extension <extension
point="org.eclipse.ui.popupMenus"> point="org.eclipse.ui.popupMenus">

View file

@ -29,13 +29,17 @@ public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
implements ISteppingControlParticipant implements ISteppingControlParticipant
{ {
public AbstractDebugVMAdapter(DsfSession session, SteppingController controller) { public AbstractDebugVMAdapter(DsfSession session, final SteppingController controller) {
super(session); super(session);
fController = controller; fController = controller;
fController.addSteppingControlParticipant(this); fController.getExecutor().execute(new DsfRunnable() {
public void run() {
fController.addSteppingControlParticipant(AbstractDebugVMAdapter.this);
}
});
} }
private SteppingController fController; private final SteppingController fController;
@Override @Override
protected IVMProvider createViewModelProvider(IPresentationContext context) { protected IVMProvider createViewModelProvider(IPresentationContext context) {
@ -56,10 +60,11 @@ public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
@Override @Override
public void dispose() { public void dispose() {
if (fController != null) { fController.getExecutor().execute(new DsfRunnable() {
fController.removeSteppingControlParticipant(this); public void run() {
fController = null; fController.removeSteppingControlParticipant(AbstractDebugVMAdapter.this);
} }
});
super.dispose(); super.dispose();
} }
} }

View file

@ -131,11 +131,6 @@ public final class SteppingController implements IStepQueueManager
*/ */
private int fMinStepInterval= 0; private int fMinStepInterval= 0;
/**
* Whether synchronized stepping is enabled.
*/
private boolean fSynchronizedStepping;
/** /**
* Map of execution contexts for which a step is in progress. * Map of execution contexts for which a step is in progress.
*/ */
@ -163,7 +158,6 @@ public final class SteppingController implements IStepQueueManager
}}; }};
store.addPropertyChangeListener(fPreferencesListener); store.addPropertyChangeListener(fPreferencesListener);
enableSynchronizedStepping(store.getBoolean(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE));
setMinimumStepInterval(store.getInt(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL)); setMinimumStepInterval(store.getInt(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL));
} }
@ -178,26 +172,6 @@ public final class SteppingController implements IStepQueueManager
fServicesTracker.dispose(); 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;
}
/**
* @return whether synchronized stepping is enabled.
*/
public boolean isSynchronizedSteppingEnabled() {
return fSynchronizedStepping;
}
/** /**
* Configure the minimum time (in milliseconds) to wait between steps. * Configure the minimum time (in milliseconds) to wait between steps.
* *
@ -375,10 +349,9 @@ public final class SteppingController implements IStepQueueManager
} }
private void doStep(final IExecutionDMContext execCtx, final StepType stepType) { private void doStep(final IExecutionDMContext execCtx, final StepType stepType) {
if (fSynchronizedStepping) { disableStepping(execCtx);
disableStepping(execCtx);
}
updateLastStepTime(execCtx); updateLastStepTime(execCtx);
getRunControl().step(execCtx, stepType, new RequestMonitor(getExecutor(), null) { getRunControl().step(execCtx, stepType, new RequestMonitor(getExecutor(), null) {
@Override @Override
protected void handleFailure() { protected void handleFailure() {
@ -492,10 +465,8 @@ public final class SteppingController implements IStepQueueManager
* @param execCtx * @param execCtx
*/ */
private void doneStepping(final IExecutionDMContext execCtx) { private void doneStepping(final IExecutionDMContext execCtx) {
if (fSynchronizedStepping) { enableStepping(execCtx);
enableStepping(execCtx); processStepQueue(execCtx);
processStepQueue(execCtx);
}
} }
/** /**
@ -513,35 +484,29 @@ public final class SteppingController implements IStepQueueManager
} }
private boolean isSteppingDisabled(IExecutionDMContext execCtx) { private boolean isSteppingDisabled(IExecutionDMContext execCtx) {
if (fSynchronizedStepping) { boolean disabled= fStepInProgress.containsKey(execCtx);
boolean disabled= fStepInProgress.containsKey(execCtx); if (!disabled) {
if (!disabled) { for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) {
for (IExecutionDMContext disabledCtx : fStepInProgress.keySet()) { if (DMContexts.isAncestorOf(execCtx, disabledCtx)) {
if (DMContexts.isAncestorOf(execCtx, disabledCtx)) { disabled = true;
disabled = true; break;
break;
}
} }
} }
if (disabled) { }
long now = System.currentTimeMillis(); if (disabled) {
long lastStepTime = getLastStepTime(execCtx); long now = System.currentTimeMillis();
if (now - lastStepTime > MAX_STEP_DELAY) { long lastStepTime = getLastStepTime(execCtx);
enableStepping(execCtx); if (now - lastStepTime > MAX_STEP_DELAY) {
disabled = false; enableStepping(execCtx);
} disabled = false;
} }
return disabled; }
} else { return disabled;
return getRunControl().isStepping(execCtx);
}
} }
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) { protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
String property = event.getProperty(); String property = event.getProperty();
if (IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE.equals(property)) { if (IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL.equals(property)) {
enableSynchronizedStepping(store.getBoolean(property));
} else if (IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL.equals(property)) {
setMinimumStepInterval(store.getInt(property)); setMinimumStepInterval(store.getInt(property));
} }
} }

View file

@ -103,10 +103,10 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
store.addPropertyChangeListener(new IPropertyChangeListener() store.addPropertyChangeListener(new IPropertyChangeListener()
{ {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
}); });
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
@Override @Override

View file

@ -94,10 +94,10 @@ public class RegisterVMProvider extends AbstractDMVMProvider
store.addPropertyChangeListener(new IPropertyChangeListener() store.addPropertyChangeListener(new IPropertyChangeListener()
{ {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
}); });
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
/* /*

View file

@ -13,6 +13,7 @@ package org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.update.action
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions.AbstractVMProviderActionDelegate; import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.actions.AbstractVMProviderActionDelegate;
import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProvider;
import org.eclipse.dd.dsf.ui.viewmodel.update.ICachingVMProviderExtension;
import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdateScope; import org.eclipse.dd.dsf.ui.viewmodel.update.IVMUpdateScope;
import org.eclipse.debug.ui.contexts.DebugContextEvent; import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IAction;
@ -45,7 +46,7 @@ public class SelectUpdateScopeAction extends AbstractVMProviderActionDelegate {
{ {
IVMProvider provider = getVMProvider(); IVMProvider provider = getVMProvider();
if (provider instanceof ICachingVMProvider) { if (provider instanceof ICachingVMProvider) {
ICachingVMProvider cachingProvider = (ICachingVMProvider)provider; ICachingVMProviderExtension cachingProvider = (ICachingVMProviderExtension)provider;
IVMUpdateScope policy = getScopeFromProvider(cachingProvider, getUpdateScopeId()); IVMUpdateScope policy = getScopeFromProvider(cachingProvider, getUpdateScopeId());
if (policy != null) { if (policy != null) {
cachingProvider.setActiveUpdateScope(policy); cachingProvider.setActiveUpdateScope(policy);
@ -54,7 +55,7 @@ public class SelectUpdateScopeAction extends AbstractVMProviderActionDelegate {
} }
} }
private IVMUpdateScope getScopeFromProvider(ICachingVMProvider provider, String id) { private IVMUpdateScope getScopeFromProvider(ICachingVMProviderExtension provider, String id) {
for (IVMUpdateScope policy : provider.getAvailableUpdateScopes()) { for (IVMUpdateScope policy : provider.getAvailableUpdateScopes()) {
if (policy.getID().equals(id)) { if (policy.getID().equals(id)) {
return policy; return policy;
@ -77,9 +78,9 @@ public class SelectUpdateScopeAction extends AbstractVMProviderActionDelegate {
protected void update() { protected void update() {
IVMProvider provider = getVMProvider(); IVMProvider provider = getVMProvider();
if (provider instanceof ICachingVMProvider) { if (provider instanceof ICachingVMProviderExtension) {
getAction().setEnabled(true); getAction().setEnabled(true);
IVMUpdateScope activeScope = ((ICachingVMProvider)provider).getActiveUpdateScope(); IVMUpdateScope activeScope = ((ICachingVMProviderExtension)provider).getActiveUpdateScope();
getAction().setChecked( activeScope != null && getUpdateScopeId().equals(activeScope.getID()) ); getAction().setChecked( activeScope != null && getUpdateScopeId().equals(activeScope.getID()) );
} else { } else {
getAction().setEnabled(false); getAction().setEnabled(false);

View file

@ -73,10 +73,10 @@ public class VariableVMProvider extends AbstractDMVMProvider
store.addPropertyChangeListener(new IPropertyChangeListener() store.addPropertyChangeListener(new IPropertyChangeListener()
{ {
public void propertyChange(PropertyChangeEvent event) { public void propertyChange(PropertyChangeEvent event) {
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
}); });
setAtomicUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE)); setDelayEventHandleForViewUpdate(store.getBoolean(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE));
} }
@Override @Override

View file

@ -78,8 +78,8 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
// sync stepping speed // sync stepping speed
BooleanFieldEditor syncSteppingEditor= new BooleanFieldEditor( BooleanFieldEditor syncSteppingEditor= new BooleanFieldEditor(
IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE, IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE,
MessagesForPreferences.DsfDebugPreferencePage_syncStepping_label, MessagesForPreferences.DsfDebugPreferencePage_waitForViewUpdate_label,
performanceGroup); performanceGroup);
syncSteppingEditor.fillIntoGrid(performanceGroup, 3); syncSteppingEditor.fillIntoGrid(performanceGroup, 3);
@ -95,15 +95,6 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
minIntervalEditor.fillIntoGrid(performanceGroup, 3); minIntervalEditor.fillIntoGrid(performanceGroup, 3);
addField(minIntervalEditor); addField(minIntervalEditor);
// atomic update
BooleanFieldEditor atomicUpdateEditor = new BooleanFieldEditor(
IDsfDebugUIConstants.PREF_ATOMIC_UPDATE_ENABLE,
MessagesForPreferences.DsfDebugPreferencePage_atomicUpdate_label,
performanceGroup);
atomicUpdateEditor.fillIntoGrid(performanceGroup, 3);
addField(atomicUpdateEditor);
// need to set layout again // need to set layout again
performanceGroup.setLayout(groupLayout); performanceGroup.setLayout(groupLayout);
} }

View file

@ -24,10 +24,8 @@ class MessagesForPreferences extends NLS {
public static String DsfDebugPreferencePage_minStepInterval_label; public static String DsfDebugPreferencePage_minStepInterval_label;
public static String DsfDebugPreferencePage_performanceGroup_label; public static String DsfDebugPreferencePage_performanceGroup_label;
public static String DsfDebugPreferencePage_syncStepping_label; public static String DsfDebugPreferencePage_waitForViewUpdate_label;
public static String DsfDebugPreferencePage_atomicUpdate_label;
static { static {
// initialize resource bundle // initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class); NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);

View file

@ -9,9 +9,8 @@
# Wind River Systems - initial API and implementation # Wind River Systems - initial API and implementation
############################################################################### ###############################################################################
DsfDebugPreferencePage_description=General settings for debugging with DSF: DsfDebugPreferencePage_description=General settings for debuggers using Debug Services Framework (DSF):
DsfDebugPreferencePage_limitStackFrames_label=Limit number of stack frames to DsfDebugPreferencePage_limitStackFrames_label=Limit number of stack frames to
DsfDebugPreferencePage_minStepInterval_label=Minimum interval between steps (in milliseconds) DsfDebugPreferencePage_minStepInterval_label=Minimum interval between steps (in milliseconds)
DsfDebugPreferencePage_performanceGroup_label=Performance DsfDebugPreferencePage_performanceGroup_label=Performance
DsfDebugPreferencePage_syncStepping_label=Synchronize stepping speed with UI updates DsfDebugPreferencePage_waitForViewUpdate_label=Wait for views to update after every step
DsfDebugPreferencePage_atomicUpdate_label=Atomic Update

View file

@ -61,7 +61,7 @@ public interface IDsfDebugUIConstants {
/** /**
* Integer preference to control the maximum amount of stack frames to * Integer preference to control the maximum amount of stack frames to
* retrieve from the backend. Default value is 10. * retrieve from the backend. Default value is <code>10</code>.
* @see {@link #PREF_STACK_FRAME_LIMIT_ENABLE} * @see {@link #PREF_STACK_FRAME_LIMIT_ENABLE}
* *
* @since 1.1 * @since 1.1
@ -77,26 +77,19 @@ public interface IDsfDebugUIConstants {
public static final String PREF_STACK_FRAME_LIMIT_ENABLE = "stackFrameLimitEnable"; //$NON-NLS-1$ public static final String PREF_STACK_FRAME_LIMIT_ENABLE = "stackFrameLimitEnable"; //$NON-NLS-1$
/** /**
* Boolean preference whether to keep stepping speed in sync with UI updates. Default is <code>true</code>. * Boolean preference whether to keep stepping speed in sync with UI updates. Default is <code>false</code>.
* *
* @since 1.1 * @since 1.1
*/ */
public static final String PREF_SYNCHRONIZED_STEPPING_ENABLE = "synchronizedSteppingEnable"; //$NON-NLS-1$ public static final String PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE = "delaySteppingForViewUpdatesEnable"; //$NON-NLS-1$
/** /**
* Integer preference to enforce a minimum time interval between steps. Default is <code>0</code>. * Integer preference to enforce a minimum time interval between steps. Default is <code>100</code>.
* *
* @since 1.1 * @since 1.1
*/ */
public static final String PREF_MIN_STEP_INTERVAL= "minStepInterval"; //$NON-NLS-1$ public static final String PREF_MIN_STEP_INTERVAL= "minStepInterval"; //$NON-NLS-1$
/**
* Boolean preference whether to wait for view update before continuing run control requests
*
* @since 1.1
*/
public static final String PREF_ATOMIC_UPDATE_ENABLE = "atomicUpdateEnable"; //$NON-NLS-1$
/** /**
* Help prefixes. * Help prefixes.
*/ */

View file

@ -59,7 +59,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer {
*/ */
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, 10); prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT, 10);
prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE, true); prefs.setDefault(IDsfDebugUIConstants.PREF_STACK_FRAME_LIMIT_ENABLE, true);
prefs.setDefault(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE, true); prefs.setDefault(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE, false);
prefs.setDefault(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL, 0); prefs.setDefault(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL, 100);
} }
} }

View file

@ -700,7 +700,7 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControl
} }
private void doneStepping(IDMContext context) { private void doneStepping(IDMContext context) {
if (fController != null && fController.isSynchronizedSteppingEnabled()) { if (fController != null) {
// indicate completion of step // indicate completion of step
final IExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class); final IExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
if (dmc != null) { if (dmc != null) {

View file

@ -15,7 +15,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -23,6 +22,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.dd.dsf.concurrent.DsfRunnable; import org.eclipse.dd.dsf.concurrent.DsfRunnable;
import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants; import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.ThreadSafe; import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin; import org.eclipse.dd.dsf.internal.ui.DsfUIPlugin;
@ -34,7 +34,6 @@ 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.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerInputUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; 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 * Base implementation for View Model Adapters. The implementation uses
@ -46,140 +45,11 @@ import org.eclipse.jface.viewers.TreePath;
abstract public class AbstractVMAdapter implements IVMAdapter abstract public class AbstractVMAdapter implements IVMAdapter
{ {
/**
* 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 boolean fDisposed;
private final Map<IPresentationContext, IVMProvider> fViewModelProviders = private final Map<IPresentationContext, IVMProvider> fViewModelProviders =
Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() ); Collections.synchronizedMap( new HashMap<IPresentationContext, IVMProvider>() );
/**
* List of IViewerUpdates pending after processing an event.
*/
private final List<IMonitoredUpdate> fPendingUpdates = new ArrayList<IMonitoredUpdate>();
/** /**
* Constructor for the View Model session. It is tempting to have the * Constructor for the View Model session. It is tempting to have the
* adapter register itself here with the session as the model adapter, but * adapter register itself here with the session as the model adapter, but
@ -260,7 +130,6 @@ abstract public class AbstractVMAdapter implements IVMAdapter
} }
private void handleUpdate(IViewerUpdate[] updates) { private void handleUpdate(IViewerUpdate[] updates) {
updates = wrapUpdates(updates);
IVMProvider provider = getVMProvider(updates[0].getPresentationContext()); IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
if (provider != null) { if (provider != null) {
updateProvider(provider, updates); updateProvider(provider, updates);
@ -351,75 +220,36 @@ abstract public class AbstractVMAdapter implements IVMAdapter
} }
if (!eventListeners.isEmpty()) { if (!eventListeners.isEmpty()) {
synchronized (fPendingUpdates) { final CountingRequestMonitor crm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), null) {
fPendingUpdates.clear();
}
// TODO which executor to use?
final Executor executor= eventListeners.get(0).getExecutor();
final CountingRequestMonitor crm = new CountingRequestMonitor(executor, null) {
@Override @Override
protected void handleCompleted() { protected void handleCompleted() {
if (isDisposed()) { if (isDisposed()) {
return; return;
} }
// The event listeners have completed processing the event. doneHandleEvent(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());
int count = 0;
for (final IVMEventListener vmEventListener : eventListeners) { for (final IVMEventListener vmEventListener : eventListeners) {
vmEventListener.getExecutor().execute(new DsfRunnable() { RequestMonitor listenerRm = null;
if (vmEventListener.shouldWaitHandleEventToComplete()) {
listenerRm = crm;
count++;
} else {
// Create a dummy executor for the handling of this event.
listenerRm = new RequestMonitor(ImmediateExecutor.getInstance(), null);
}
final RequestMonitor finalListenerRm = listenerRm;
vmEventListener.getExecutor().execute(new DsfRunnable() {
public void run() { public void run() {
vmEventListener.handleEvent(event, crm); vmEventListener.handleEvent(event, finalListenerRm);
}}); }});
} }
crm.setDoneCount(count);
} }
} }
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. * Given event is about to be handled.
* *

View file

@ -385,6 +385,10 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
return false; return false;
} }
public boolean shouldWaitHandleEventToComplete() {
return false;
}
public IRootVMNode getRootVMNode() { public IRootVMNode getRootVMNode() {
return fRootNode; return fRootNode;
} }
@ -597,7 +601,7 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
*/ */
public void updateNode(IVMNode node, IChildrenUpdate update) { public void updateNode(IVMNode node, IChildrenUpdate update) {
if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) { if (DEBUG_CONTENT_PROVIDER && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) {
DsfUIPlugin.debug("updateNodeChildren(node = " + node + ", update = " + update + ")"); DsfUIPlugin.debug("updateNodeChildren(node = " + node + ", update = " + update + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
} }
node.update(new IChildrenUpdate[] { update }); node.update(new IChildrenUpdate[] { update });
} }

View file

@ -29,5 +29,12 @@ public interface IVMEventListener {
/** /**
* Process the given event and indicate completion with request monitor. * Process the given event and indicate completion with request monitor.
*/ */
public abstract void handleEvent(final Object event, RequestMonitor rm); public void handleEvent(final Object event, RequestMonitor rm);
/**
* Returns whether the event handling manager should wait for this listener
* to complete handling this event, or whether the event listener can process
* the event asynchronously.
*/
public boolean shouldWaitHandleEventToComplete();
} }

View file

@ -65,7 +65,7 @@ import org.eclipse.swt.widgets.TreeItem;
@SuppressWarnings("restriction") @SuppressWarnings("restriction")
public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider, ICachingVMProviderExtension { public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider, ICachingVMProviderExtension {
private boolean fIsAtomicUpdate = false; private boolean fDelayEventHandleForViewUpdate = false;
// debug flags // debug flags
public static boolean DEBUG_CACHE = false; public static boolean DEBUG_CACHE = false;
@ -725,7 +725,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
if (proxyStrategy instanceof IVMModelProxyExtension) { if (proxyStrategy instanceof IVMModelProxyExtension) {
IVMModelProxyExtension proxyStrategyExtension = (IVMModelProxyExtension)proxyStrategy; IVMModelProxyExtension proxyStrategyExtension = (IVMModelProxyExtension)proxyStrategy;
if(fIsAtomicUpdate) { if(fDelayEventHandleForViewUpdate) {
if(this.getActiveUpdateScope().getID().equals(AllUpdateScope.ALL_UPDATE_SCOPE_ID)) { if(this.getActiveUpdateScope().getID().equals(AllUpdateScope.ALL_UPDATE_SCOPE_ID)) {
updateExpanded( updateExpanded(
proxyStrategyExtension, proxyStrategyExtension,
@ -821,7 +821,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
{ {
List<Object> pathList = new LinkedList<Object>(); List<Object> pathList = new LinkedList<Object>();
TreeItem item = child.getParentItem(); TreeItem item = child.getParentItem();
Tree tree = null;
while (item != null) { while (item != null) {
pathList.add(0, item.getData()); pathList.add(0, item.getData());
item = item.getParentItem(); item = item.getParentItem();
@ -1253,12 +1252,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
getPresentationContext().setProperty(SELECTED_UPDATE_SCOPE, updateScope.getID()); getPresentationContext().setProperty(SELECTED_UPDATE_SCOPE, updateScope.getID());
} }
public boolean isAtomicUpdate() { public boolean shouldWaitHandleEventToComplete() {
return fIsAtomicUpdate; return fDelayEventHandleForViewUpdate;
} }
public void setAtomicUpdate(boolean enable) { protected void setDelayEventHandleForViewUpdate(boolean on) {
fIsAtomicUpdate = enable; fDelayEventHandleForViewUpdate = on;
} }
} }

View file

@ -35,32 +35,6 @@ public interface ICachingVMProvider extends IVMProvider {
*/ */
public void setActiveUpdatePolicy(IVMUpdatePolicy mode); public void setActiveUpdatePolicy(IVMUpdatePolicy mode);
/**
* Returns the update policies that the given provider supports.
*/
public IVMUpdateScope[] getAvailableUpdateScopes();
/**
* Returns the active update policy.
*/
public IVMUpdateScope getActiveUpdateScope();
/**
* Sets the active update policy. This has to be one of the update
* policies supported by the provider.
*/
public void setActiveUpdateScope(IVMUpdateScope mode);
/**
* Is update atomic?
*/
public boolean isAtomicUpdate();
/**
* Sets atomic update.
*/
public void setAtomicUpdate(boolean enable);
/** /**
* Forces the view to flush its cache and re-fetch data from the view * Forces the view to flush its cache and re-fetch data from the view
* model nodes. * model nodes.

View file

@ -12,13 +12,23 @@ package org.eclipse.dd.dsf.ui.viewmodel.update;
/** /**
* * @since 1.1
*/ */
public interface ICachingVMProviderExtension extends ICachingVMProvider { public interface ICachingVMProviderExtension extends ICachingVMProvider {
/**
public boolean isAtomicUpdate(); * Returns the update policies that the given provider supports.
*/
public void setAtomicUpdate(boolean enable); public IVMUpdateScope[] getAvailableUpdateScopes();
/**
* Returns the active update policy.
*/
public IVMUpdateScope getActiveUpdateScope();
/**
* Sets the active update policy. This has to be one of the update
* policies supported by the provider.
*/
public void setActiveUpdateScope(IVMUpdateScope mode);
} }