diff options
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java')
-rw-r--r-- | org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java | 119 |
1 files changed, 101 insertions, 18 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java index 24e0b712d..589a4f493 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java @@ -53,6 +53,7 @@ import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.progress.WorkbenchJob; /** * Content provider for a virtual tree. @@ -77,7 +78,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * Used to install different model proxy instances for one element depending * on the tree path. */ - private Map<TreePath, IModelProxy> fTreeModelProxies = new HashMap<TreePath, IModelProxy>(); // tree + private Map<TreePath, IModelProxy> fTreeModelProxies = new HashMap<>(); // tree // model // proxy // by @@ -89,7 +90,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * Used to install a single model proxy which is responsible for all * instances of an element in the model tree. */ - private Map<Object, IModelProxy> fModelProxies = new HashMap<Object, IModelProxy>(); // model + private Map<Object, IModelProxy> fModelProxies = new HashMap<>(); // model // proxy // by // element @@ -118,15 +119,15 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon /** * Map of updates in progress: element path -> list of requests */ - private Map<TreePath, List<ViewerUpdateMonitor>> fRequestsInProgress = new HashMap<TreePath, List<ViewerUpdateMonitor>>(); + private Map<TreePath, List<ViewerUpdateMonitor>> fRequestsInProgress = new HashMap<>(); /** * Map of dependent requests waiting for parent requests to complete: * element path -> list of requests */ - private Map<TreePath, List<ViewerUpdateMonitor>> fWaitingRequests = new HashMap<TreePath, List<ViewerUpdateMonitor>>(); + private Map<TreePath, List<ViewerUpdateMonitor>> fWaitingRequests = new HashMap<>(); - private List<ViewerUpdateMonitor> fCompletedUpdates = new ArrayList<ViewerUpdateMonitor>(); + private List<ViewerUpdateMonitor> fCompletedUpdates = new ArrayList<>(); private Runnable fCompletedUpdatesRunnable; @@ -158,6 +159,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (fViewer == null) { return; } + fDelayedDoModelChangeJob.shutdown(); Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); @@ -382,6 +384,92 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } } + private static class DelayedDoModelChange { + public final IModelDelta delta; + public final IModelProxy proxy; + + public DelayedDoModelChange(final IModelDelta delta, final IModelProxy proxy) { + this.delta = delta; + this.proxy = proxy; + } + } + + private class DelayedDoModelChangedJob extends WorkbenchJob { + + // queue of submitted deltas to process + private final List<DelayedDoModelChange> fQueue = new ArrayList<>(); + private boolean shutdown; + + public DelayedDoModelChangedJob() { + super("Delayed model change job"); //$NON-NLS-1$ + setSystem(true); + setUser(false); + } + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + List<DelayedDoModelChange> currentBatch = new ArrayList<>(); + synchronized (fQueue) { + if (shutdown || fQueue.isEmpty()) { + return Status.OK_STATUS; + } + currentBatch = new ArrayList<>(fQueue); + fQueue.clear(); + } + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) { + DebugUIPlugin.trace("Delayed batch size: " + currentBatch.size()); //$NON-NLS-1$ + } + for (Iterator<DelayedDoModelChange> iterator = currentBatch.iterator(); iterator.hasNext();) { + DelayedDoModelChange change = iterator.next(); + if (monitor.isCanceled()) { + restoreQueue(currentBatch); + return Status.CANCEL_STATUS; + } + if (!change.proxy.isDisposed()) { + doModelChanged(change.delta, change.proxy); + } + iterator.remove(); + } + return Status.OK_STATUS; + } + + private void restoreQueue(List<DelayedDoModelChange> currentBatch) { + synchronized (fQueue) { + currentBatch.addAll(fQueue); + fQueue.clear(); + fQueue.addAll(currentBatch); + } + } + + public void runDelayed(final IModelDelta delta, final IModelProxy proxy) { + synchronized (fQueue) { + if (shutdown) { + return; + } + fQueue.add(new DelayedDoModelChange(delta, proxy)); + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) { + DebugUIPlugin.trace("Delayed queue size: " + fQueue.size()); //$NON-NLS-1$ + } + } + schedule(50); + } + + public void shutdown() { + synchronized (fQueue) { + shutdown = true; + fQueue.clear(); + } + cancel(); + } + + @Override + public boolean belongsTo(Object family) { + return family == TreeModelContentProvider.this || family == TreeModelContentProvider.class; + } + } + + private final DelayedDoModelChangedJob fDelayedDoModelChangeJob = new DelayedDoModelChangedJob(); + @Override public void modelChanged(final IModelDelta delta, final IModelProxy proxy) { Display display = null; @@ -400,12 +488,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon doModelChanged(delta, proxy); } else { - fViewer.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - doModelChanged(delta, proxy); - } - }); + fDelayedDoModelChangeJob.runDelayed(delta, proxy); } } } @@ -469,7 +552,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @return corresponding tree path */ TreePath getFullTreePath(IModelDelta node) { - ArrayList<Object> list = new ArrayList<Object>(); + ArrayList<Object> list = new ArrayList<>(); while (node.getParentDelta() != null) { list.add(0, node.getElement()); node = node.getParentDelta(); @@ -485,7 +568,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @return corresponding tree path */ TreePath getViewerTreePath(IModelDelta node) { - ArrayList<Object> list = new ArrayList<Object>(); + ArrayList<Object> list = new ArrayList<>(); IModelDelta parentDelta = node.getParentDelta(); while (parentDelta != null) { list.add(0, node.getElement()); @@ -624,7 +707,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(update.getSchedulingPath()); if (requests == null) { - requests = new ArrayList<ViewerUpdateMonitor>(); + requests = new ArrayList<>(); fRequestsInProgress.put(update.getSchedulingPath(), requests); } requests.add(update); @@ -783,7 +866,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } } } - List<TreePath> purge = new ArrayList<TreePath>(); + List<TreePath> purge = new ArrayList<>(); for (TreePath entryPath : fWaitingRequests.keySet()) { if (entryPath.startsWith(path, null)) { purge.add(entryPath); @@ -808,7 +891,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon TreePath schedulingPath = update.getSchedulingPath(); List<ViewerUpdateMonitor> requests = fWaitingRequests.get(schedulingPath); if (requests == null) { - requests = new LinkedList<ViewerUpdateMonitor>(); + requests = new LinkedList<>(); requests.add(update); fWaitingRequests.put(schedulingPath, requests); @@ -1019,7 +1102,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon childrenUpdate.cancel(); iterator.remove(); if (reCreate == null) { - reCreate = new ArrayList<IChildrenUpdate>(); + reCreate = new ArrayList<>(); } reCreate.add(childrenUpdate); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { @@ -1728,7 +1811,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } jobCompletedUpdates = fCompletedUpdates; fCompletedUpdatesRunnable = null; - fCompletedUpdates = new ArrayList<ViewerUpdateMonitor>(); + fCompletedUpdates = new ArrayList<>(); } // necessary to check if viewer is disposed try { |