Bug 390379 - [Performance] Seemingly excessive calls to contextManager
diff --git a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
index ce839b9..90629d3 100644
--- a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
+++ b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
@@ -25,6 +25,10 @@
private IEclipseContext eclipseContext;
private ContextManager contextManager;
+
+ private boolean deferUpdates = false;
+
+ private int cachingRef = 0;
public ContextContextService(IEclipseContext context) {
eclipseContext = context;
@@ -40,6 +44,10 @@
* String)
*/
public void activateContext(String id) {
+ if (deferUpdates) {
+ deferActivateContext(id);
+ return;
+ }
LinkedList<String> locals = (LinkedList<String>) eclipseContext
.getLocal(LOCAL_CONTEXTS);
if (locals == null) {
@@ -54,7 +62,76 @@
}
}
}
+
+ /**
+ * Informs the manager that a batch operation has started.
+ * <p>
+ * <b>Note:</b> You must insure that if you call
+ * <code>deferUpdates(true)</code> that nothing in your batched operation
+ * will prevent the matching call to <code>deferUpdates(false)</code>.
+ * </p>
+ *
+ * @param defer
+ * true when starting a batch operation false when ending the
+ * operation
+ *
+ * @since 4.3
+ */
+ public void deferUpdates(boolean defer) {
+ if(defer) {
+ cachingRef ++;
+ if (cachingRef==1) {
+ setEventCaching(true);
+ }
+ }else {
+ cachingRef--;
+ if (cachingRef==0) {
+ setEventCaching(false);
+ }
+ }
+ }
+ private void deferActivateContext(String id) {
+ LinkedList<String> locals = (LinkedList<String>) eclipseContext
+ .getLocal(LOCAL_CONTEXTS+".a");
+ if (locals == null) {
+ locals = new LinkedList<String>();
+ eclipseContext.set(LOCAL_CONTEXTS+ ".a", locals);
+ }
+ locals.add(id);
+ }
+
+ private void setEventCaching(boolean cache) {
+ if (cache) {
+ deferUpdates = true;
+ return;
+ }
+
+ deferUpdates = false;
+ LinkedList<String> locals = (LinkedList<String>) eclipseContext
+ .getLocal(LOCAL_CONTEXTS);
+ if (locals == null) {
+ locals = new LinkedList<String>();
+ }
+ LinkedList<String> activates = (LinkedList<String>) eclipseContext
+ .getLocal(LOCAL_CONTEXTS + ".a");
+ if (activates != null) {
+ eclipseContext.remove(LOCAL_CONTEXTS + ".a");
+ for (String id : activates) {
+ locals.add(id);
+ }
+ }
+ LinkedList<String> deactivates = (LinkedList<String>) eclipseContext
+ .getLocal(LOCAL_CONTEXTS + ".d");
+ if (deactivates != null) {
+ eclipseContext.remove(LOCAL_CONTEXTS + ".d");
+ for (String id : deactivates) {
+ locals.remove(id);
+ }
+ }
+ eclipseContext.set(LOCAL_CONTEXTS, locals.clone());
+ }
+
/*
* (non-Javadoc)
*
@@ -63,6 +140,10 @@
* .String)
*/
public void deactivateContext(String id) {
+ if (deferUpdates) {
+ deferDeactivateContext(id);
+ return;
+ }
LinkedList<String> locals = (LinkedList<String>) eclipseContext
.getLocal(LOCAL_CONTEXTS);
if (locals != null && locals.remove(id)) {
@@ -74,6 +155,16 @@
}
}
+ private void deferDeactivateContext(String id) {
+ LinkedList<String> locals = (LinkedList<String>) eclipseContext
+ .getLocal(LOCAL_CONTEXTS+".d");
+ if (locals == null) {
+ locals = new LinkedList<String>();
+ eclipseContext.set(LOCAL_CONTEXTS+ ".d", locals);
+ }
+ locals.add(id);
+ }
+
/*
* (non-Javadoc)
*
diff --git a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/services/EContextService.java b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/services/EContextService.java
index ffaa03b..a754b2c 100644
--- a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/services/EContextService.java
+++ b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/services/EContextService.java
@@ -22,4 +22,6 @@
public void deactivateContext(String id);
public Collection<String> getActiveContextIds();
+
+ public void deferUpdates(boolean defer);
}
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
index 20138a8..89df348 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
@@ -46,6 +46,7 @@
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.e4.ui.services.EContextService;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
@@ -125,6 +126,9 @@
@Inject
private IEventBroker eventBroker;
+ @Inject
+ private EContextService contextService;
+
private PartActivationHistory partActivationHistory;
private MPart activePart;
@@ -544,32 +548,37 @@
UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
return;
}
+ contextService.deferUpdates(true);
+ try {
+ // record any sibling into the activation history if necessary, this will allow it to be
+ // reselected again in the future as it will be an activation candidate in the future,
+ // this
+ // prevents other unrendered elements from being selected arbitrarily which would cause
+ // unwanted bundle activation
+ recordStackActivation(part);
- // record any sibling into the activation history if necessary, this will allow it to be
- // reselected again in the future as it will be an activation candidate in the future, this
- // prevents other unrendered elements from being selected arbitrarily which would cause
- // unwanted bundle activation
- recordStackActivation(part);
+ delegateBringToTop(part);
+ window.getParent().setSelectedElement(window);
- delegateBringToTop(part);
- window.getParent().setSelectedElement(window);
+ partActivationHistory.activate(part, activateBranch);
- partActivationHistory.activate(part, activateBranch);
+ Object object = part.getObject();
+ if (object != null && requiresFocus) {
+ try {
+ ContextInjectionFactory.invoke(object, Focus.class, part.getContext(), null);
- Object object = part.getObject();
- if (object != null && requiresFocus) {
- try {
- ContextInjectionFactory.invoke(object, Focus.class, part.getContext(), null);
-
- firePartActivated(part);
- UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
- } catch (InjectionException e) {
- log("Failed to grant focus to part", "Failed to grant focus to part ({0})", //$NON-NLS-1$ //$NON-NLS-2$
- part.getElementId(), e);
- } catch (RuntimeException e) {
- log("Failed to grant focus to part via DI", //$NON-NLS-1$
- "Failed to grant focus via DI to part ({0})", part.getElementId(), e); //$NON-NLS-1$
+ firePartActivated(part);
+ UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
+ } catch (InjectionException e) {
+ log("Failed to grant focus to part", "Failed to grant focus to part ({0})", //$NON-NLS-1$ //$NON-NLS-2$
+ part.getElementId(), e);
+ } catch (RuntimeException e) {
+ log("Failed to grant focus to part via DI", //$NON-NLS-1$
+ "Failed to grant focus via DI to part ({0})", part.getElementId(), e); //$NON-NLS-1$
+ }
}
+ } finally {
+ contextService.deferUpdates(false);
}
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
index f471cbe..4205cbc 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
@@ -92,6 +92,7 @@
*/
public void deferUpdates(boolean defer) {
contextManager.deferUpdates(defer);
+ contextService.deferUpdates(defer);
}
/*