From dfee10f094e2155699767a14034bc136f168f083 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 25 Nov 2013 13:49:00 +0400 Subject: [PATCH] error reporting in 'Project Structure' dialog: merge UI updates (IDEA-116808, IDEA-110799) --- .../ProjectStructureDaemonAnalyzer.java | 128 ++++++++++++------ 1 file changed, 90 insertions(+), 38 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index 8b551b0f38f9..97ed5b0da733 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -7,13 +7,13 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.util.Alarm; import com.intellij.util.EventDispatcher; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,6 +29,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { private final Set myElementsToShowWarningIfUnused = new HashSet(); private final Map myWarningsAboutUnused = new HashMap(); private final MergingUpdateQueue myAnalyzerQueue; + private final MergingUpdateQueue myResultsUpdateQueue; private final EventDispatcher myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class); private final AtomicBoolean myStopped = new AtomicBoolean(false); private final ProjectConfigurationProblems myProjectConfigurationProblems; @@ -36,7 +37,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) { Disposer.register(context, this); myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context); - myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, false); + myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, Alarm.ThreadToUse.POOLED_THREAD); + myResultsUpdateQueue = new MergingUpdateQueue("Project Structure Analysis Results Updater", 300, false, MergingUpdateQueue.ANY_COMPONENT, + this, null, Alarm.ThreadToUse.SWING_THREAD); } private void doUpdate(final ProjectStructureElement element, final boolean check, final boolean collectUsages) { @@ -63,21 +66,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { ProjectStructureValidator.check(element, problemsHolder); } }.execute(); - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get()) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating problems for " + element); - } - final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element); - if (warning != null) - problemsHolder.registerProblem(warning); - myProblemHolders.put(element, problemsHolder); - myDispatcher.getMulticaster().problemsChanged(element); - } - }); + myResultsUpdateQueue.queue(new ProblemsComputedUpdate(element, problemsHolder)); } private void doCollectUsages(final ProjectStructureElement element) { @@ -92,18 +81,9 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { result.setResult(getUsagesInElement(element)); } }.execute().getResultObject(); - - invokeLater(new Runnable() { - @Override - public void run() { - if (myStopped.get() || usages == null) return; - - if (LOG.isDebugEnabled()) { - LOG.debug("updating usages for " + element); - } - updateUsages(element, usages); - } - }); + if (usages != null) { + myResultsUpdateQueue.queue(new UsagesCollectedUpdate(element, usages)); + } } private static List getUsagesInElement(final ProjectStructureElement element) { @@ -116,11 +96,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { addUsage(usage); } myElementWithNotCalculatedUsages.remove(element); - reportUnusedElements(); - } - - private static void invokeLater(Runnable runnable) { - SwingUtilities.invokeLater(runnable); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } public void queueUpdate(@NotNull final ProjectStructureElement element) { @@ -159,7 +135,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { removeUsagesInElement(element); myDispatcher.getMulticaster().problemsChanged(element); } - reportUnusedElements(); + myResultsUpdateQueue.queue(new ReportUnusedElementsUpdate()); } @@ -212,8 +188,10 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { LOG.debug("analyzer stopped"); myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); clearCaches(); myAnalyzerQueue.deactivate(); + myResultsUpdateQueue.deactivate(); } public void clearCaches() { @@ -239,6 +217,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void dispose() { myStopped.set(true); myAnalyzerQueue.cancelAllUpdates(); + myResultsUpdateQueue.cancelAllUpdates(); } @Nullable @@ -263,6 +242,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { public void reset() { LOG.debug("analyzer started"); myAnalyzerQueue.activate(); + myResultsUpdateQueue.activate(); myAnalyzerQueue.queue(new Update("reset") { @Override public void run() { @@ -277,9 +257,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { mySourceElement2Usages.clear(); myContainingElement2Usages.clear(); myElementWithNotCalculatedUsages.clear(); - if (myProjectConfigurationProblems != null) { - myProjectConfigurationProblems.clearProblems(); - } + myProjectConfigurationProblems.clearProblems(); } private class AnalyzeElementUpdate extends Update { @@ -319,4 +297,78 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { } } } + + private class UsagesCollectedUpdate extends Update { + private final ProjectStructureElement myElement; + private final List myUsages; + private final Object[] myEqualityObjects; + + public UsagesCollectedUpdate(ProjectStructureElement element, List usages) { + super(element); + myElement = element; + myUsages = usages; + myEqualityObjects = new Object[]{element, "usages collected"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating usages for " + myElement); + } + updateUsages(myElement, myUsages); + } + } + + private class ProblemsComputedUpdate extends Update { + private final ProjectStructureElement myElement; + private final ProjectStructureProblemsHolderImpl myProblemsHolder; + private final Object[] myEqualityObjects; + + public ProblemsComputedUpdate(ProjectStructureElement element, ProjectStructureProblemsHolderImpl problemsHolder) { + super(element); + myElement = element; + myProblemsHolder = problemsHolder; + myEqualityObjects = new Object[]{element, "problems computed"}; + } + + @NotNull + @Override + public Object[] getEqualityObjects() { + return myEqualityObjects; + } + + @Override + public void run() { + if (myStopped.get()) return; + + if (LOG.isDebugEnabled()) { + LOG.debug("updating problems for " + myElement); + } + final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(myElement); + if (warning != null) { + myProblemsHolder.registerProblem(warning); + } + myProblemHolders.put(myElement, myProblemsHolder); + myDispatcher.getMulticaster().problemsChanged(myElement); + } + } + + private class ReportUnusedElementsUpdate extends Update { + private ReportUnusedElementsUpdate() { + super("unused elements"); + } + + @Override + public void run() { + reportUnusedElements(); + } + } }