mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-02 06:35:28 +02:00
[246640] - [run control][update policy] Stepping should always be synchronized with painting the IP
This commit is contained in:
parent
cfe2a71e89
commit
0e70351e3f
20 changed files with 117 additions and 341 deletions
|
@ -12,7 +12,7 @@ pluginName=Debug Services Framework Debug UI
|
|||
providerName=Eclipse.org
|
||||
|
||||
# disassembly
|
||||
disassemblyPreferencePage.name = DSF Disassembly
|
||||
disassemblyPreferencePage.name = Disassembly
|
||||
disassemblyView.name= DSF Disassembly
|
||||
|
||||
command.gotoPC.name=Go to Program Counter
|
||||
|
@ -51,7 +51,7 @@ action.setDefaultNumberFormatOctal.label = Octal
|
|||
action.setDefaultNumberFormatBinary.label = Binary
|
||||
action.setDefaultNumberFormatNatural.label = Natural
|
||||
|
||||
preferencePage.name = DSF Performance
|
||||
preferencePage.name = DSF
|
||||
|
||||
action.expandStack.label = E&xpand Stack
|
||||
|
||||
|
|
|
@ -527,17 +527,17 @@
|
|||
|
||||
<extension
|
||||
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
|
||||
category="org.eclipse.debug.ui.DebugPreferencePage"
|
||||
class="org.eclipse.dd.dsf.debug.internal.ui.preferences.DsfDebugPreferencePage"
|
||||
id="org.eclipse.dd.dsf.debug.ui.preferences"
|
||||
name="%preferencePage.name">
|
||||
</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
|
||||
point="org.eclipse.ui.popupMenus">
|
||||
|
|
|
@ -29,13 +29,17 @@ public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
|
|||
implements ISteppingControlParticipant
|
||||
{
|
||||
|
||||
public AbstractDebugVMAdapter(DsfSession session, SteppingController controller) {
|
||||
public AbstractDebugVMAdapter(DsfSession session, final SteppingController controller) {
|
||||
super(session);
|
||||
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
|
||||
protected IVMProvider createViewModelProvider(IPresentationContext context) {
|
||||
|
@ -56,10 +60,11 @@ public class AbstractDebugVMAdapter extends AbstractDMVMAdapter
|
|||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (fController != null) {
|
||||
fController.removeSteppingControlParticipant(this);
|
||||
fController = null;
|
||||
}
|
||||
fController.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
fController.removeSteppingControlParticipant(AbstractDebugVMAdapter.this);
|
||||
}
|
||||
});
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,11 +131,6 @@ public final class SteppingController implements IStepQueueManager
|
|||
*/
|
||||
private int fMinStepInterval= 0;
|
||||
|
||||
/**
|
||||
* Whether synchronized stepping is enabled.
|
||||
*/
|
||||
private boolean fSynchronizedStepping;
|
||||
|
||||
/**
|
||||
* Map of execution contexts for which a step is in progress.
|
||||
*/
|
||||
|
@ -163,7 +158,6 @@ public final class SteppingController implements IStepQueueManager
|
|||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
|
||||
enableSynchronizedStepping(store.getBoolean(IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE));
|
||||
setMinimumStepInterval(store.getInt(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL));
|
||||
}
|
||||
|
||||
|
@ -178,26 +172,6 @@ public final class SteppingController implements IStepQueueManager
|
|||
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.
|
||||
*
|
||||
|
@ -375,10 +349,9 @@ public final class SteppingController implements IStepQueueManager
|
|||
}
|
||||
|
||||
private void doStep(final IExecutionDMContext execCtx, final StepType stepType) {
|
||||
if (fSynchronizedStepping) {
|
||||
disableStepping(execCtx);
|
||||
}
|
||||
disableStepping(execCtx);
|
||||
updateLastStepTime(execCtx);
|
||||
|
||||
getRunControl().step(execCtx, stepType, new RequestMonitor(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleFailure() {
|
||||
|
@ -492,10 +465,8 @@ public final class SteppingController implements IStepQueueManager
|
|||
* @param execCtx
|
||||
*/
|
||||
private void doneStepping(final IExecutionDMContext execCtx) {
|
||||
if (fSynchronizedStepping) {
|
||||
enableStepping(execCtx);
|
||||
processStepQueue(execCtx);
|
||||
}
|
||||
enableStepping(execCtx);
|
||||
processStepQueue(execCtx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -513,35 +484,29 @@ public final class SteppingController implements IStepQueueManager
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
return getRunControl().isStepping(execCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disabled) {
|
||||
long now = System.currentTimeMillis();
|
||||
long lastStepTime = getLastStepTime(execCtx);
|
||||
if (now - lastStepTime > MAX_STEP_DELAY) {
|
||||
enableStepping(execCtx);
|
||||
disabled = false;
|
||||
}
|
||||
}
|
||||
return disabled;
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL.equals(property)) {
|
||||
setMinimumStepInterval(store.getInt(property));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,10 +103,10 @@ public class ExpressionVMProvider extends AbstractDMVMProvider
|
|||
store.addPropertyChangeListener(new IPropertyChangeListener()
|
||||
{
|
||||
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
|
||||
|
|
|
@ -94,10 +94,10 @@ public class RegisterVMProvider extends AbstractDMVMProvider
|
|||
store.addPropertyChangeListener(new IPropertyChangeListener()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.ui.viewmodel.IVMProvider;
|
||||
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.debug.ui.contexts.DebugContextEvent;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
|
@ -45,7 +46,7 @@ public class SelectUpdateScopeAction extends AbstractVMProviderActionDelegate {
|
|||
{
|
||||
IVMProvider provider = getVMProvider();
|
||||
if (provider instanceof ICachingVMProvider) {
|
||||
ICachingVMProvider cachingProvider = (ICachingVMProvider)provider;
|
||||
ICachingVMProviderExtension cachingProvider = (ICachingVMProviderExtension)provider;
|
||||
IVMUpdateScope policy = getScopeFromProvider(cachingProvider, getUpdateScopeId());
|
||||
if (policy != null) {
|
||||
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()) {
|
||||
if (policy.getID().equals(id)) {
|
||||
return policy;
|
||||
|
@ -77,9 +78,9 @@ public class SelectUpdateScopeAction extends AbstractVMProviderActionDelegate {
|
|||
|
||||
protected void update() {
|
||||
IVMProvider provider = getVMProvider();
|
||||
if (provider instanceof ICachingVMProvider) {
|
||||
if (provider instanceof ICachingVMProviderExtension) {
|
||||
getAction().setEnabled(true);
|
||||
IVMUpdateScope activeScope = ((ICachingVMProvider)provider).getActiveUpdateScope();
|
||||
IVMUpdateScope activeScope = ((ICachingVMProviderExtension)provider).getActiveUpdateScope();
|
||||
getAction().setChecked( activeScope != null && getUpdateScopeId().equals(activeScope.getID()) );
|
||||
} else {
|
||||
getAction().setEnabled(false);
|
||||
|
|
|
@ -73,10 +73,10 @@ public class VariableVMProvider extends AbstractDMVMProvider
|
|||
store.addPropertyChangeListener(new IPropertyChangeListener()
|
||||
{
|
||||
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
|
||||
|
|
|
@ -78,8 +78,8 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
|
|||
|
||||
// sync stepping speed
|
||||
BooleanFieldEditor syncSteppingEditor= new BooleanFieldEditor(
|
||||
IDsfDebugUIConstants.PREF_SYNCHRONIZED_STEPPING_ENABLE,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_syncStepping_label,
|
||||
IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE,
|
||||
MessagesForPreferences.DsfDebugPreferencePage_waitForViewUpdate_label,
|
||||
performanceGroup);
|
||||
|
||||
syncSteppingEditor.fillIntoGrid(performanceGroup, 3);
|
||||
|
@ -95,15 +95,6 @@ public class DsfDebugPreferencePage extends FieldEditorPreferencePage implements
|
|||
minIntervalEditor.fillIntoGrid(performanceGroup, 3);
|
||||
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
|
||||
performanceGroup.setLayout(groupLayout);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,8 @@ class MessagesForPreferences extends NLS {
|
|||
public static String DsfDebugPreferencePage_minStepInterval_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 {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, MessagesForPreferences.class);
|
||||
|
|
|
@ -9,9 +9,8 @@
|
|||
# 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_minStepInterval_label=Minimum interval between steps (in milliseconds)
|
||||
DsfDebugPreferencePage_performanceGroup_label=Performance
|
||||
DsfDebugPreferencePage_syncStepping_label=Synchronize stepping speed with UI updates
|
||||
DsfDebugPreferencePage_atomicUpdate_label=Atomic Update
|
||||
DsfDebugPreferencePage_waitForViewUpdate_label=Wait for views to update after every step
|
||||
|
|
|
@ -61,7 +61,7 @@ public interface IDsfDebugUIConstants {
|
|||
|
||||
/**
|
||||
* 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}
|
||||
*
|
||||
* @since 1.1
|
||||
|
@ -77,26 +77,19 @@ public interface IDsfDebugUIConstants {
|
|||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -59,7 +59,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);
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_WAIT_FOR_VIEW_UPDATE_AFTER_STEP_ENABLE, false);
|
||||
prefs.setDefault(IDsfDebugUIConstants.PREF_MIN_STEP_INTERVAL, 100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -700,7 +700,7 @@ public class DsfSourceDisplayAdapter implements ISourceDisplay, ISteppingControl
|
|||
}
|
||||
|
||||
private void doneStepping(IDMContext context) {
|
||||
if (fController != null && fController.isSynchronizedSteppingEnabled()) {
|
||||
if (fController != null) {
|
||||
// indicate completion of step
|
||||
final IExecutionDMContext dmc = DMContexts.getAncestorOfType(context, IExecutionDMContext.class);
|
||||
if (dmc != null) {
|
||||
|
|
|
@ -15,7 +15,6 @@ 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;
|
||||
|
@ -23,6 +22,7 @@ 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.ImmediateExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
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.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
|
||||
|
@ -46,140 +45,11 @@ import org.eclipse.jface.viewers.TreePath;
|
|||
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 final Map<IPresentationContext, IVMProvider> fViewModelProviders =
|
||||
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
|
||||
* 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) {
|
||||
updates = wrapUpdates(updates);
|
||||
IVMProvider provider = getVMProvider(updates[0].getPresentationContext());
|
||||
if (provider != null) {
|
||||
updateProvider(provider, updates);
|
||||
|
@ -351,75 +220,36 @@ abstract public class AbstractVMAdapter implements IVMAdapter
|
|||
}
|
||||
|
||||
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) {
|
||||
final CountingRequestMonitor crm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), 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();
|
||||
}
|
||||
doneHandleEvent(event);
|
||||
}
|
||||
};
|
||||
crm.setDoneCount(eventListeners.size());
|
||||
|
||||
|
||||
int count = 0;
|
||||
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() {
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -385,6 +385,10 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldWaitHandleEventToComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public IRootVMNode getRootVMNode() {
|
||||
return fRootNode;
|
||||
}
|
||||
|
@ -597,7 +601,7 @@ abstract public class AbstractVMProvider implements IVMProvider, IVMEventListene
|
|||
*/
|
||||
public void updateNode(IVMNode node, IChildrenUpdate update) {
|
||||
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 });
|
||||
}
|
||||
|
|
|
@ -29,5 +29,12 @@ public interface IVMEventListener {
|
|||
/**
|
||||
* 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();
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ import org.eclipse.swt.widgets.TreeItem;
|
|||
@SuppressWarnings("restriction")
|
||||
public class AbstractCachingVMProvider extends AbstractVMProvider implements ICachingVMProvider, ICachingVMProviderExtension {
|
||||
|
||||
private boolean fIsAtomicUpdate = false;
|
||||
private boolean fDelayEventHandleForViewUpdate = false;
|
||||
|
||||
// debug flags
|
||||
public static boolean DEBUG_CACHE = false;
|
||||
|
@ -725,7 +725,7 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
|
||||
if (proxyStrategy instanceof IVMModelProxyExtension) {
|
||||
IVMModelProxyExtension proxyStrategyExtension = (IVMModelProxyExtension)proxyStrategy;
|
||||
if(fIsAtomicUpdate) {
|
||||
if(fDelayEventHandleForViewUpdate) {
|
||||
if(this.getActiveUpdateScope().getID().equals(AllUpdateScope.ALL_UPDATE_SCOPE_ID)) {
|
||||
updateExpanded(
|
||||
proxyStrategyExtension,
|
||||
|
@ -821,7 +821,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
{
|
||||
List<Object> pathList = new LinkedList<Object>();
|
||||
TreeItem item = child.getParentItem();
|
||||
Tree tree = null;
|
||||
while (item != null) {
|
||||
pathList.add(0, item.getData());
|
||||
item = item.getParentItem();
|
||||
|
@ -1253,12 +1252,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider implements ICa
|
|||
getPresentationContext().setProperty(SELECTED_UPDATE_SCOPE, updateScope.getID());
|
||||
}
|
||||
|
||||
public boolean isAtomicUpdate() {
|
||||
return fIsAtomicUpdate;
|
||||
}
|
||||
public boolean shouldWaitHandleEventToComplete() {
|
||||
return fDelayEventHandleForViewUpdate;
|
||||
}
|
||||
|
||||
public void setAtomicUpdate(boolean enable) {
|
||||
fIsAtomicUpdate = enable;
|
||||
protected void setDelayEventHandleForViewUpdate(boolean on) {
|
||||
fDelayEventHandleForViewUpdate = on;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,32 +35,6 @@ public interface ICachingVMProvider extends IVMProvider {
|
|||
*/
|
||||
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
|
||||
* model nodes.
|
||||
|
|
|
@ -12,13 +12,23 @@ package org.eclipse.dd.dsf.ui.viewmodel.update;
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public interface ICachingVMProviderExtension extends ICachingVMProvider {
|
||||
|
||||
|
||||
public boolean isAtomicUpdate();
|
||||
|
||||
public void setAtomicUpdate(boolean enable);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue