From 7c8d11496ed98164527ddd9bba0d98e071323680 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Fri, 8 Oct 2010 18:10:14 +0000 Subject: [PATCH] Bug 327358 - [variables][vm] "Wait for views to update after every step" preference doesn't always work --- .../META-INF/MANIFEST.MF | 1 - .../actions/UpdateScopesContribution.java | 110 -------- .../actions/UpdateScopesPropertyTester.java | 78 ------ .../update/provisional/AllUpdateScope.java | 34 --- .../ICachingVMProviderExtension.java | 36 --- .../update/provisional/IVMUpdateScope.java | 28 -- .../provisional/VisibleUpdateScope.java | 34 --- .../update/AbstractCachingVMProvider.java | 263 ++++++++++-------- .../update/MultiLevelUpdateHandler.java | 239 ---------------- 9 files changed, 144 insertions(+), 679 deletions(-) delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesContribution.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesPropertyTester.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/AllUpdateScope.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/ICachingVMProviderExtension.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/IVMUpdateScope.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/VisibleUpdateScope.java delete mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/MultiLevelUpdateHandler.java diff --git a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF index 13caa310237..19672f3604f 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF @@ -35,7 +35,6 @@ Export-Package: org.eclipse.cdt.dsf.debug.internal.ui;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.actions;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.detailsupport;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.numberformat.detail;x-internal:=true, - org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional;x-internal:=true, org.eclipse.cdt.dsf.debug.ui, org.eclipse.cdt.dsf.debug.ui.actions, org.eclipse.cdt.dsf.debug.ui.contexts, diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesContribution.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesContribution.java deleted file mode 100644 index 7b0295b2cba..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesContribution.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.actions; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.ICachingVMProviderExtension; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.IVMUpdateScope; -import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.VMHandlerUtils; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.jface.action.IContributionItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.ui.actions.CompoundContributionItem; -import org.eclipse.ui.menus.IWorkbenchContribution; -import org.eclipse.ui.services.IServiceLocator; - -/** - * Dynamic menu contribution that shows available update scopes - * in the current view. - * - * @since 1.1 - */ -public class UpdateScopesContribution extends CompoundContributionItem implements IWorkbenchContribution { - - private class SelectUpdateScopeAction extends Action { - private final ICachingVMProviderExtension fProvider; - private final IVMUpdateScope fScope; - SelectUpdateScopeAction(ICachingVMProviderExtension provider, IVMUpdateScope scope) { - super(scope.getName(), AS_RADIO_BUTTON); - fProvider = provider; - fScope = scope; - } - - @Override - public void run() { - if (isChecked()) { - fProvider.setActiveUpdateScope(fScope); - } - } - } - - private IServiceLocator fServiceLocator; - - private static IContributionItem[] NO_BREAKPOINT_TYPES_CONTRIBUTION_ITEMS = new IContributionItem[] { - new ContributionItem() { - @Override - public void fill(Menu menu, int index) { - MenuItem item = new MenuItem(menu, SWT.NONE); - item.setEnabled(false); - item.setText(MessagesForVMActions.UpdateScopesContribution_EmptyScopesList_label); - } - - @Override - public boolean isEnabled() { - return false; - } - } - }; - - @Override - protected IContributionItem[] getContributionItems() { - IVMProvider provider = VMHandlerUtils.getActiveVMProvider(fServiceLocator); - - // If no part or selection, disable all. - if (provider == null || !(provider instanceof ICachingVMProviderExtension)) { - return NO_BREAKPOINT_TYPES_CONTRIBUTION_ITEMS; - } - ICachingVMProviderExtension cachingProvider = (ICachingVMProviderExtension)provider; - - IVMUpdateScope[] scopes = cachingProvider.getAvailableUpdateScopes(); - IVMUpdateScope activeScope = cachingProvider.getActiveUpdateScope(); - - List actions = new ArrayList(scopes.length); - for (IVMUpdateScope scope : scopes) { - Action action = new SelectUpdateScopeAction(cachingProvider, scope); - if (scope.getID().equals(activeScope.getID())) { - action.setChecked(true); - } - actions.add(action); - } - - if ( actions.isEmpty() ) { - return NO_BREAKPOINT_TYPES_CONTRIBUTION_ITEMS; - } - - IContributionItem[] items = new IContributionItem[actions.size()]; - for (int i = 0; i < actions.size(); i++) { - items[i] = new ActionContributionItem(actions.get(i)); - } - return items; - } - - public void initialize(IServiceLocator serviceLocator) { - fServiceLocator = serviceLocator; - } -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesPropertyTester.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesPropertyTester.java deleted file mode 100644 index 04777f2b0e1..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/actions/UpdateScopesPropertyTester.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.actions; - -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.ICachingVMProviderExtension; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.IVMUpdateScope; -import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.VMHandlerUtils; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider; -import org.eclipse.core.expressions.PropertyTester; -import org.eclipse.debug.ui.IDebugView; -import org.eclipse.ui.IWorkbenchPart; - -/** - * Property tester for update scope information available through the given - * object. The object being tested should be either an {@link IVMContext}, - * through which an instance of {@link ICachingVMProviderExtension} could be obtained. - * Or it could be an {@link IWorkbenchPart}, which is tested to see if it - * is a debug view through which a caching VM provider can be obtained. - * The Caching View Model provider is used to test the given property. - *

- * Three properties are supported: - *

    - *
  • "areUpdateScopesSupported" - Checks whether update scopes are - * available at all given the receiver.
  • - *
  • "isUpdateScopeAvailable" - Checks whether the update scope in the - * expected value is available for the given receiver.
  • - *
  • "isUpdateScopeActive" - Checks whether the scope given in the expected - * value is the currently active scope for the given receiver.
  • - *
- *

- */ -public class UpdateScopesPropertyTester extends PropertyTester { - - private static final String SUPPORTED = "areUpdateScopesSupported"; //$NON-NLS-1$ - private static final String AVAILABLE = "isUpdateScopeAvailable"; //$NON-NLS-1$ - private static final String ACTIVE = "isUpdateScopeActive"; //$NON-NLS-1$ - - public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { - if (receiver instanceof IVMContext) { - IVMProvider provider = ((IVMContext)receiver).getVMNode().getVMProvider(); - if (provider instanceof ICachingVMProviderExtension) { - return testProvider((ICachingVMProviderExtension)provider, property, expectedValue); - } - } else if (receiver instanceof IDebugView) { - IVMProvider provider = VMHandlerUtils.getVMProviderForPart((IDebugView)receiver); - if (provider instanceof ICachingVMProviderExtension) { - return testProvider((ICachingVMProviderExtension)provider, property, expectedValue); - } - } - return false; - } - - private boolean testProvider(ICachingVMProviderExtension provider, String property, Object expectedValue) { - if (SUPPORTED.equals(property)) { - return true; - } else if (AVAILABLE.equals(property)) { - for (IVMUpdateScope scope : provider.getAvailableUpdateScopes()) { - if (scope.getID().equals(expectedValue)) { - return true; - } - return false; - } - } else if (ACTIVE.equals(property)) { - return expectedValue != null && expectedValue.equals(provider.getActiveUpdateScope().getID()); - } - return false; - } - -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/AllUpdateScope.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/AllUpdateScope.java deleted file mode 100644 index 2b24b7f2ad3..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/AllUpdateScope.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.update.provisional; - -import org.eclipse.cdt.dsf.ui.viewmodel.update.ViewModelUpdateMessages; - - -/** - * An "automatic" update policy which causes the view model provider cache to - * be flushed whenever an event causes a delta to be generated in the given - * model. - * - * @since 1.1 - */ -public class AllUpdateScope implements IVMUpdateScope { - - public static String ALL_UPDATE_SCOPE_ID = "org.eclipse.cdt.dsf.ui.viewmodel.update.allUpdateScope"; //$NON-NLS-1$ - - public String getID() { - return ALL_UPDATE_SCOPE_ID; - } - - public String getName() { - return ViewModelUpdateMessages.AllUpdateScope_name; - } -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/ICachingVMProviderExtension.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/ICachingVMProviderExtension.java deleted file mode 100644 index 76e46e5db17..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/ICachingVMProviderExtension.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.update.provisional; - -import org.eclipse.cdt.dsf.ui.viewmodel.update.ICachingVMProvider; - - -/** - * @since 1.1 - */ -public interface ICachingVMProviderExtension extends ICachingVMProvider { - - /** - * 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); -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/IVMUpdateScope.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/IVMUpdateScope.java deleted file mode 100644 index 2576ae1c749..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/IVMUpdateScope.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.update.provisional; - - -/** - * @since 1.1 - */ -public interface IVMUpdateScope { - - /** - * Returns unique ID of this update policy. - */ - public String getID(); - - /** - * Returns the user-presentable name of this update policy. - */ - public String getName(); -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/VisibleUpdateScope.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/VisibleUpdateScope.java deleted file mode 100644 index b204948f921..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/viewmodel/update/provisional/VisibleUpdateScope.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2009 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.cdt.dsf.debug.internal.ui.viewmodel.update.provisional; - -import org.eclipse.cdt.dsf.ui.viewmodel.update.ViewModelUpdateMessages; - - -/** - * An "automatic" update policy which causes the view model provider cache to - * be flushed whenever an event causes a delta to be generated in the given - * model. - * - * @since 1.1 - */ -public class VisibleUpdateScope implements IVMUpdateScope { - - public static String VISIBLE_UPDATE_SCOPE_ID = "org.eclipse.cdt.dsf.ui.viewmodel.update.visibleUpdateScope"; //$NON-NLS-1$ - - public String getID() { - return VISIBLE_UPDATE_SCOPE_ID; - } - - public String getName() { - return ViewModelUpdateMessages.VisibleUpdateScope_name; - } -} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java index ad244d76c7c..0323463de24 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/AbstractCachingVMProvider.java @@ -25,10 +25,8 @@ import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.AllUpdateScope; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.ICachingVMProviderExtension; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.IVMUpdateScope; -import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.update.provisional.VisibleUpdateScope; +import org.eclipse.cdt.dsf.internal.DsfPlugin; +import org.eclipse.cdt.dsf.internal.LoggingUtils; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor; import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor; @@ -49,15 +47,14 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; 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.IViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta; import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeItem; /** * Base implementation of a caching view model provider. @@ -65,7 +62,7 @@ import org.eclipse.swt.widgets.TreeItem; * @since 1.0 */ public class AbstractCachingVMProvider extends AbstractVMProvider - implements ICachingVMProvider, IElementPropertiesProvider, ICachingVMProviderExtension, ICachingVMProviderExtension2 + implements ICachingVMProvider, IElementPropertiesProvider, ICachingVMProviderExtension2 { /** * @since 2.0 @@ -361,7 +358,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider protected static String SELECTED_UPDATE_SCOPE = "org.eclipse.cdt.dsf.ui.viewmodel.update.selectedUpdateScope"; //$NON-NLS-1$ private IVMUpdatePolicy[] fAvailableUpdatePolicies; - private IVMUpdateScope[] fAvailableUpdateScopes; public Map fRootMarkers = new HashMap(); @@ -395,22 +391,12 @@ public class AbstractCachingVMProvider extends AbstractVMProvider fCacheListHead.fPrevious = fCacheListHead; fAvailableUpdatePolicies = createUpdateModes(); - - fAvailableUpdateScopes = createUpdateScopes(); - setActiveUpdateScope(new VisibleUpdateScope()); } protected IVMUpdatePolicy[] createUpdateModes() { return new IVMUpdatePolicy[] { new AutomaticUpdatePolicy() }; } - - /** - * @since 1.1 - */ - protected IVMUpdateScope[] createUpdateScopes() { - return new IVMUpdateScope[] { new VisibleUpdateScope(), new AllUpdateScope() }; - } - + public IVMUpdatePolicy[] getAvailableUpdatePolicies() { return fAvailableUpdatePolicies; } @@ -807,78 +793,106 @@ public class AbstractCachingVMProvider extends AbstractVMProvider flushMarkerEntry.insert(fCacheListHead); } + /** + * Listener used to detect when the viewer is finished updating itself + * after a model event. The + */ + // Warnings for use of ITreeModelViewer. ITreeModelViewer is an internal + // interface in platform, but it is more generic than the public TreeModelViewer. + // Using ITreeModelViewer will allow us to write unit tests using the + // VirtualTreeModelViewer. + @SuppressWarnings("restriction") + private class ViewUpdateFinishedListener implements IViewerUpdateListener, IModelChangedListener { + private final org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer fViewer; + private boolean fViewerChangeStarted = false; + private RequestMonitor fRm; + + ViewUpdateFinishedListener(org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer viewer) { + fViewer = viewer; + } + + private void start(RequestMonitor rm) { + synchronized(this) { + fViewer.addModelChangedListener(this); + fViewer.addViewerUpdateListener(this); + fRm = rm; + } + } + + public synchronized void viewerUpdatesComplete() { + done(); + } + + public void modelChanged(IModelDelta delta, IModelProxy proxy) { + synchronized (this) { + if (!fViewerChangeStarted) { + done(); + } + } + } + + public void viewerUpdatesBegin() { + synchronized(this) { + fViewerChangeStarted = true; + } + } + + private synchronized void done() { + if (fRm != null) { + fRm.done(); + fViewer.removeViewerUpdateListener(this); + fViewer.removeModelChangedListener(this); + } + } + + public void updateStarted(IViewerUpdate update) {} + public void updateComplete(IViewerUpdate update) {} + + } + @Override protected void handleEvent(final IVMModelProxy proxyStrategy, final Object event, final RequestMonitor rm) { IElementUpdateTester elementTester = getActiveUpdatePolicy().getElementUpdateTester(event); flush(new FlushMarkerKey(proxyStrategy.getRootElement(), elementTester)); - CountingRequestMonitor multiRm = new CountingRequestMonitor(getExecutor(), rm); - super.handleEvent(proxyStrategy, event, multiRm); - int rmCount = 1; - - if(fDelayEventHandleForViewUpdate) { - if(this.getActiveUpdateScope().getID().equals(AllUpdateScope.ALL_UPDATE_SCOPE_ID)) { - new MultiLevelUpdateHandler(getExecutor(), proxyStrategy, getPresentationContext(), this, multiRm). - startUpdate(); - rmCount++; - } else if (!proxyStrategy.isDisposed()) { - // block updating only the viewport - TreeViewer viewer = (TreeViewer) proxyStrategy.getViewer(); - Tree tree = viewer.getTree(); - int count = tree.getSize().y / tree.getItemHeight(); - - TreeItem topItem = tree.getTopItem(); - int index = computeTreeIndex(topItem); - - MultiLevelUpdateHandler handler = new MultiLevelUpdateHandler( - getExecutor(), proxyStrategy, getPresentationContext(), this, multiRm); - handler.setRange(index, index + count); - handler.startUpdate(); - rmCount++; - } + if (!proxyStrategy.isDisposed()) { + if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) { + trace(event, null, proxyStrategy, EventHandlerAction.processing); + } + proxyStrategy.createDelta( + event, + new DataRequestMonitor(getExecutor(), rm) { + @Override + public void handleSuccess() { + if (DEBUG_DELTA && (DEBUG_PRESENTATION_ID == null || getPresentationContext().getId().equals(DEBUG_PRESENTATION_ID))) { + trace(event, null, proxyStrategy, EventHandlerAction.firedDeltaFor); + } + + // If we need to wait for the view to finish updating, then before posting the delta to the + // viewer install a listener, which will in turn call rm.done(). + if (fDelayEventHandleForViewUpdate) { + @SuppressWarnings("restriction") + org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer viewer = + (org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer) proxyStrategy.getViewer(); + new ViewUpdateFinishedListener(viewer).start(rm); + } + + proxyStrategy.fireModelChanged(getData()); + + if (!fDelayEventHandleForViewUpdate) { + rm.done(); + } + } + @Override public String toString() { + return "Result of a delta for event: '" + event.toString() + "' in VMP: '" + AbstractCachingVMProvider.this + "'" + "\n" + getData().toString(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + }); } else { - if(this.getActiveUpdateScope().getID().equals(AllUpdateScope.ALL_UPDATE_SCOPE_ID)) { - MultiLevelUpdateHandler handler = new MultiLevelUpdateHandler( - getExecutor(), proxyStrategy, getPresentationContext(), this, multiRm); - handler.startUpdate(); - rmCount++; - } + rm.done(); } - multiRm.setDoneCount(rmCount); } - private static int computeTreeIndex(TreeItem child) { - if (child != null) { - if(child.getParentItem() != null) { - int previous = 0; - int index = child.getParentItem().indexOf(child); - while (--index >= 0) { - previous += computeTreeExtent(child.getParentItem().getItem(index)); - } - return computeTreeIndex(child.getParentItem()) + previous; - } else { - int previous = 0; - int index = child.getParent().indexOf(child); - while (--index >= 0) { - previous += computeTreeExtent(child.getParent().getItem(index)); - } - return previous; - } - } - return 0; - } - - private static int computeTreeExtent(TreeItem item) { - int extent = 1; - if (item.getExpanded()) { - for (TreeItem i : item.getItems()) { - extent += computeTreeExtent(i); - } - } - return extent; - } - /** * Override default implementation to avoid automatically removing disposed proxies from * list of active proxies. The caching provider only removes a proxy after its root element @@ -1297,43 +1311,6 @@ public class AbstractCachingVMProvider extends AbstractVMProvider } } - /** - * @noreference This method is an implementation of a provisional interface and - * not intended to be referenced by clients. - * @since 1.1 - */ - public IVMUpdateScope[] getAvailableUpdateScopes() { - return fAvailableUpdateScopes; - } - - /** - * @noreference This method is an implementation of a provisional interface and - * not intended to be referenced by clients. - * @since 1.1 - */ - public IVMUpdateScope getActiveUpdateScope() { - String updateScopeId = (String)getPresentationContext().getProperty(SELECTED_UPDATE_SCOPE); - if (updateScopeId != null) { - for (IVMUpdateScope updateScope : getAvailableUpdateScopes()) { - if (updateScope.getID().equals(updateScopeId)) { - return updateScope; - } - } - } - - // Default to the first one. - return getAvailableUpdateScopes()[0]; - } - - /** - * @noreference This method is an implementation of a provisional interface and - * not intended to be referenced by clients. - * @since 1.1 - */ - public void setActiveUpdateScope(IVMUpdateScope updateScope) { - getPresentationContext().setProperty(SELECTED_UPDATE_SCOPE, updateScope.getID()); - } - @Override public boolean shouldWaitHandleEventToComplete() { return fDelayEventHandleForViewUpdate; @@ -1346,4 +1323,52 @@ public class AbstractCachingVMProvider extends AbstractVMProvider fDelayEventHandleForViewUpdate = on; } + /** + * Used for tracing event handling + *

+ * Note: this enum is duplicated from AbstractVMProvider. + */ + private enum EventHandlerAction { + received, + queued, + processing, + firedDeltaFor, + skipped, + canceled + } + + /** + * Trace that we've reached a particular phase of the handling of an event + * for a particular proxy. + *

+ * Note: this method is duplicated from AbstractVMProvider. + * + * @param event + * the event being handled + * @param skippedOrCanceledEvent + * for a 'skip' or 'cancel' action, this is the event that is + * being dismissed. Otherwise null + * @param proxy + * the target proxy; n/a (null) for a 'received' action. + * @param action + * what phased of the event handling has beeb reached + */ + private void trace(Object event, Object skippedOrCanceledEvent, IVMModelProxy proxy, EventHandlerAction action) { + assert DEBUG_DELTA; + StringBuilder str = new StringBuilder(); + str.append(DsfPlugin.getDebugTime()); + str.append(' '); + if (action == EventHandlerAction.skipped || action == EventHandlerAction.canceled) { + str.append(LoggingUtils.toString(this) + " " + action.toString() + " event " + LoggingUtils.toString(skippedOrCanceledEvent) + " because of event " + LoggingUtils.toString(event)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + else { + str.append(LoggingUtils.toString(this) + " " + action.toString() + " event " + LoggingUtils.toString(event)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + if (action != EventHandlerAction.received) { + str.append(" for proxy " + LoggingUtils.toString(proxy) + ", whose root is " + LoggingUtils.toString(proxy.getRootElement())); //$NON-NLS-1$ //$NON-NLS-2$ + } + DsfUIPlugin.debug(str.toString()); + } + } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/MultiLevelUpdateHandler.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/MultiLevelUpdateHandler.java deleted file mode 100644 index 4949608edf7..00000000000 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/update/MultiLevelUpdateHandler.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.cdt.dsf.ui.viewmodel.update; - -import java.util.List; -import java.util.Stack; -import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionException; - -import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; -import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; -import org.eclipse.cdt.dsf.concurrent.DsfRunnable; -import org.eclipse.cdt.dsf.concurrent.RequestMonitor; -import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy; -import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate; -import org.eclipse.cdt.dsf.ui.viewmodel.VMHasChildrenUpdate; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; -import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.RGB; - -/** - * @since 1.1 - */ -class MultiLevelUpdateHandler extends DataRequestMonitor> { - - private static final boolean DEBUG = Boolean.parseBoolean(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/vm/atomicUpdate")); //$NON-NLS-1$ //; - - private static final class UpdateLevel { - private final List fChildren; - private final TreePath fPath; - private int fChildIndex; - private UpdateLevel(TreePath path, List children) { - fPath = path; - fChildren = children; - fChildIndex = 0; - assert !isDone(); - } - private boolean isDone() { - return fChildIndex == fChildren.size(); - } - private Object nextChild() { - if (isDone()) { - return null; - } - return fChildren.get(fChildIndex++); - } - } - private final class DummyLabelUpdate implements ILabelUpdate { - private final RequestMonitor fMonitor; - private final Object fData; - private final TreePath fPath; - - private DummyLabelUpdate(Object data, TreePath path, RequestMonitor rm) { - fMonitor= rm; - fData= data; - fPath= path; - } - public Object getElement() { - return fData; - } - public TreePath getElementPath() { - return fPath.createChildPath(fData); - } - public IPresentationContext getPresentationContext() { - return fPresentationContext; - } - public Object getViewerInput() { - return fViewerInput; - } - public void cancel() { } - public IStatus getStatus() { - return null; - } - public boolean isCanceled() { - return false; - } - public void setStatus(IStatus status) { } - public String[] getColumnIds() { - return fColumns; - } - public void setBackground(RGB arg0, int arg1) { } - public void setFontData(FontData arg0, int arg1) { } - public void setForeground(RGB arg0, int arg1) { } - public void setImageDescriptor(ImageDescriptor arg0, int arg1) { } - public void setLabel(String arg0, int arg1) { - } - public void done() { - fMonitor.done(); - } - } - - private final Executor fExecutor; - private final IElementContentProvider fContentProvider; - private final IPresentationContext fPresentationContext; - private final String[] fColumns; - private final Viewer fViewer; - private final Object fViewerInput; - private final Stack fStack = new Stack(); - private final CountingRequestMonitor fRequestMonitor; - - private int fIndex = 0; - private TreePath fCurrentPath; - private int fLowIndex = 0; - private int fHighIndex = Integer.MAX_VALUE - 1; - private int fPendingUpdates; - private boolean fIsDone; - - public MultiLevelUpdateHandler(Executor executor, - IVMModelProxy modelProxy, - IPresentationContext presentationContext, - IElementContentProvider contentProvider, - RequestMonitor parentRequestMonitor) { - super(executor, null); - fExecutor = executor; - fViewer = modelProxy.getViewer(); - fViewerInput = modelProxy.getViewerInput(); - fCurrentPath = modelProxy.getRootPath(); - fPresentationContext = presentationContext; - fColumns = presentationContext.getColumns(); - fContentProvider = contentProvider; - - fRequestMonitor = new CountingRequestMonitor(fExecutor, parentRequestMonitor); - } - void startUpdate() { - if (DEBUG) System.out.println("[MultiLevelUpdateHandler] startUpdate " + fLowIndex + '-' + fHighIndex); //$NON-NLS-1$ - fContentProvider.update(new IChildrenUpdate[] { - new VMChildrenUpdate(fCurrentPath, fViewerInput, fPresentationContext, -1, -1, this) - }); - } - void setRange(int low, int high) { - fLowIndex = low; - fHighIndex = high; - } - @Override - public synchronized void done() { - assert !fIsDone; - if (fIsDone) { - // ignore gracefully - return; - } - try { - fExecutor.execute(new DsfRunnable() { - public void run() { - final List data= getData(); - if (data != null && !data.isEmpty()) { - if (DEBUG) System.out.println("[MultiLevelUpdateHandler] gotChildUpdate " + data.size()); //$NON-NLS-1$ - fStack.push(new UpdateLevel(fCurrentPath, data)); - } - processNext(); - } - @Override - public String toString() { - return "Completed: " + MultiLevelUpdateHandler.this.toString(); //$NON-NLS-1$ - } - }); - } catch (RejectedExecutionException e) { - handleRejectedExecutionException(); - } - } - protected void processNext() { - while (true) { - if (fIndex > fHighIndex) { - fStack.clear(); - } - if (fStack.isEmpty()) { - fIsDone = true; - fRequestMonitor.setDoneCount(fPendingUpdates); - super.done(); - return; - } - UpdateLevel current = fStack.peek(); - assert !current.isDone(); - - TreePath path = current.fPath; - Object data = current.nextChild(); - if (current.isDone()) { - fStack.pop(); - } - if (data == null) { - // consider null children - http://bugs.eclipse.org/250309 - ++fIndex; - continue; - } - path = path.createChildPath(data); - - if (fIndex >= fLowIndex && fIndex <= fHighIndex) { - if(data instanceof IAdaptable) { - IElementLabelProvider labelProvider = (IElementLabelProvider) ((IAdaptable)data).getAdapter(IElementLabelProvider.class); - if (labelProvider != null) { - ++fPendingUpdates; - if (DEBUG) System.out.println("[MultiLevelUpdateHandler] labelUpdate " + data); //$NON-NLS-1$ - labelProvider.update(new ILabelUpdate[] { - new DummyLabelUpdate(data, path, fRequestMonitor) - }); - } - } - } - fIndex++; - if (fViewer instanceof TreeViewer) { - TreeViewer treeViewer = (TreeViewer) fViewer; - if (treeViewer.getExpandedState(data)) { - fCurrentPath = path; - if (DEBUG) System.out.println("[MultiLevelUpdateHandler] childrenUpdate " + data); //$NON-NLS-1$ - fContentProvider.update(new IChildrenUpdate[] { - new VMChildrenUpdate(path, fViewerInput, fPresentationContext, -1, -1, this) - }); - return; - } else if (fIndex >= fLowIndex) { - // update also the hasChildren flag - ++fPendingUpdates; - if (DEBUG) System.out.println("[MultiLevelUpdateHandler] hasChildUpdate " + data); //$NON-NLS-1$ - fContentProvider.update(new IHasChildrenUpdate[] { - new VMHasChildrenUpdate(path, fViewerInput, fPresentationContext, new DataRequestMonitor(fExecutor, fRequestMonitor)) - }); - } - } - } - } -}