diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolItemUpdater.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolItemUpdater.java index 9f888cb2f46..e55f8643bc9 100644 --- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolItemUpdater.java +++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/ToolItemUpdater.java @@ -47,11 +47,13 @@ void removeItem(AbstractContributionItem item) { } public void updateContributionItems(Selector selector) { + boolean queued = false; boolean doRunNow = false; for (final AbstractContributionItem ci : itemsToCheck) { if (ci.getModel() != null && ci.getModel().getParent() != null) { if (selector.select(ci.getModel())) { itemsToUpdateLater.add(ci); + queued = true; if (timestampOfEarliestQueuedUpdate == 0) { timestampOfEarliestQueuedUpdate = System.nanoTime(); } @@ -61,14 +63,16 @@ public void updateContributionItems(Selector selector) { // again and again in less than given DELAY frequency. TimerExec would then // never be executed. doRunNow = true; - } else { - Display.getDefault().timerExec(DELAY, this); } } } else { orphanedToolItems.add(ci); } } + if (queued && !doRunNow) { + // one timer for the whole batch, rescheduling it per item only costs time + Display.getDefault().timerExec(DELAY, this); + } if (!orphanedToolItems.isEmpty()) { itemsToCheck.removeAll(orphanedToolItems); orphanedToolItems.clear(); diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchPage.java index 11073f4f801..325e6d283fa 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchPage.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchPage.java @@ -42,6 +42,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -1061,12 +1062,14 @@ public EditorReference createEditorReferenceForPart(final MPart part, IEditorInp private List getOrderedEditorReferences() { List editorRefs = new ArrayList<>(); + Set seen = new HashSet<>(); + Map referencesByModel = getEditorReferencesByModel(); List visibleEditors = modelService.findElements(window, CompatibilityEditor.MODEL_ELEMENT_ID, MPart.class); for (MPart editor : visibleEditors) { if (editor.isToBeRendered()) { - EditorReference ref = getEditorReference(editor); - if (ref != null && !editorRefs.contains(ref)) { + EditorReference ref = referencesByModel.get(editor); + if (ref != null && seen.add(ref)) { editorRefs.add(ref); } } @@ -1075,23 +1078,36 @@ private List getOrderedEditorReferences() { return editorRefs; } + /** + * Maps the model element of every editor reference of this page to its + * reference, so that callers can resolve many parts without rescanning the + * reference list for each one. + */ + private Map getEditorReferencesByModel() { + Map referencesByModel = new IdentityHashMap<>(editorReferences.size()); + for (EditorReference ref : editorReferences) { + referencesByModel.putIfAbsent(ref.getModel(), ref); + } + return referencesByModel; + } + List getSortedEditorReferences() { return getSortedEditorReferences(false); } private List getSortedEditorReferences(boolean allPerspectives) { + Map referencesByModel = getEditorReferencesByModel(); List sortedReferences = new ArrayList<>(); + Set seen = new HashSet<>(); for (MPart part : activationList) { - for (EditorReference ref : editorReferences) { - if (ref.getModel() == part) { - sortedReferences.add(ref); - break; - } + EditorReference ref = referencesByModel.get(part); + if (ref != null && seen.add(ref)) { + sortedReferences.add(ref); } } for (EditorReference ref : editorReferences) { - if (!sortedReferences.contains(ref)) { + if (seen.add(ref)) { sortedReferences.add(ref); } } @@ -1101,13 +1117,17 @@ private List getSortedEditorReferences(boolean allPerspectives) int scope = allPerspectives ? WINDOW_SCOPE : EModelService.PRESENTATION; List placeholders = modelService.findElements(window, CompatibilityEditor.MODEL_ELEMENT_ID, MPart.class, null, scope); + // only rendered placeholders are valid references + Set rendered = Collections.newSetFromMap(new IdentityHashMap<>(placeholders.size())); + for (MPart placeholder : placeholders) { + if (placeholder.isToBeRendered()) { + rendered.add(placeholder); + } + } List visibleReferences = new ArrayList<>(); for (EditorReference reference : sortedReferences) { - for (MPart placeholder : placeholders) { - if (reference.getModel() == placeholder && placeholder.isToBeRendered()) { - // only rendered placeholders are valid references - visibleReferences.add(reference); - } + if (rendered.contains(reference.getModel())) { + visibleReferences.add(reference); } } @@ -2318,32 +2338,36 @@ private IWorkbenchPartReference[] getSortedParts(boolean editors, boolean views, } List sortedReferences = new ArrayList<>(); + Set seen = new HashSet<>(); IViewReference[] viewReferences = getViewReferences(allPerspectives); List editorReferences = getSortedEditorReferences(allPerspectives); - activationLoop: for (MPart part : activationList) { - if (views) { - for (IViewReference ref : viewReferences) { - if (((ViewReference) ref).getModel() == part) { - sortedReferences.add(ref); - continue activationLoop; - } - } + Map viewsByModel = new IdentityHashMap<>(viewReferences.length); + if (views) { + for (IViewReference ref : viewReferences) { + viewsByModel.putIfAbsent(((ViewReference) ref).getModel(), ref); + } + } + Map editorsByModel = new IdentityHashMap<>(editorReferences.size()); + if (editors) { + for (EditorReference ref : editorReferences) { + editorsByModel.putIfAbsent(ref.getModel(), ref); } + } - if (editors) { - for (EditorReference ref : editorReferences) { - if (ref.getModel() == part) { - sortedReferences.add(ref); - break; - } - } + for (MPart part : activationList) { + IWorkbenchPartReference ref = viewsByModel.get(part); + if (ref == null) { + ref = editorsByModel.get(part); + } + if (ref != null && seen.add(ref)) { + sortedReferences.add(ref); } } if (views) { for (IViewReference ref : viewReferences) { - if (!sortedReferences.contains(ref)) { + if (seen.add(ref)) { sortedReferences.add(ref); } } @@ -2351,7 +2375,7 @@ private IWorkbenchPartReference[] getSortedParts(boolean editors, boolean views, if (editors) { for (EditorReference ref : editorReferences) { - if (!sortedReferences.contains(ref)) { + if (seen.add(ref)) { sortedReferences.add(ref); } }