CPP-8459: don't calculate usage text in EDT

Review: IDEA-CR-32232
This commit is contained in:
Dmitry Kozhevnikov
2018-05-30 14:02:29 +03:00
parent 4f5cb24fe0
commit 02431cd1b8
6 changed files with 53 additions and 4 deletions
@@ -432,6 +432,22 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
@Override
@NotNull
public TextChunk[] getText() {
return doUpdateCachedText();
}
@Nullable
@Override
public TextChunk[] getCachedText() {
return SoftReference.dereference(myTextChunks);
}
@Override
public void updateCachedText() {
doUpdateCachedText();
}
@NotNull
private TextChunk[] doUpdateCachedText() {
TextChunk[] chunks = SoftReference.dereference(myTextChunks);
final long currentModificationStamp = getCurrentModificationStamp();
boolean isModified = currentModificationStamp != myModificationStamp;
@@ -16,6 +16,7 @@
package com.intellij.usages;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -26,6 +27,20 @@ public interface UsagePresentation {
@NotNull
TextChunk[] getText();
/**
* If the implementation caches or lazy-loades the text chunks internally, this method gives it a chance to avoid
* re-calculating it synchronously on EDT and return the possibly obsolete data.
*
* The component using this presentation might call {@link UsagePresentation#updateCachedText()} in a background
* thread and then use {@link UsagePresentation#getCachedText()} to draw the text.
*/
@Nullable
default TextChunk[] getCachedText() {
return getText();
}
default void updateCachedText() {}
@NotNull
String getPlainText();
@@ -67,6 +67,8 @@ public abstract class Node extends DefaultMutableTreeNode {
protected abstract boolean isDataReadOnly();
protected abstract boolean isDataExcluded();
protected void updateCachedPresentation() {}
@NotNull
protected abstract String getText(@NotNull UsageView view);
@@ -98,6 +100,7 @@ public abstract class Node extends DefaultMutableTreeNode {
boolean isDataValid = isDataValid();
boolean isReadOnly = isDataReadOnly();
String text = getText(view);
updateCachedPresentation();
doUpdate(edtNodeChangedQueue, isDataValid, isReadOnly, text);
}
@@ -93,4 +93,9 @@ public class UsageNode extends Node implements Comparable<UsageNode>, Navigatabl
protected String getText(@NotNull final UsageView view) {
return getUsage().getPresentation().getPlainText();
}
@Override
protected void updateCachedPresentation() {
getUsage().getPresentation().updateCachedText();
}
}
@@ -1419,7 +1419,7 @@ public class UsageViewImpl implements UsageViewEx {
}
}
private void updateLater() {
void updateLater() {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(() -> {
if (myProject.isDisposed()) return;
@@ -49,14 +49,15 @@ class UsageViewTreeCellRenderer extends ColoredTreeCellRenderer {
private static final SimpleTextAttributes ourNumberOfUsagesAttribute = SimpleTextAttributes.fromTextAttributes(ourColorsScheme.getAttributes(UsageTreeColors.NUMBER_OF_USAGES));
private static final SimpleTextAttributes ourInvalidAttributesDarcula = new SimpleTextAttributes(null, DarculaColors.RED, null, ourInvalidAttributes.getStyle());
private static final Insets STANDARD_IPAD_NOWIFI = new Insets(1, 2, 1, 2);
private static final TextChunk[] ourLoadingText = {new TextChunk(SimpleTextAttributes.GRAY_ATTRIBUTES.toTextAttributes(), "loading...")};
private boolean myRowBoundsCalled;
private final UsageViewPresentation myPresentation;
private final UsageView myView;
private final UsageViewImpl myView;
private boolean myCalculated;
private int myRowHeight = AllIcons.Nodes.AbstractClass.getIconHeight()+2;
UsageViewTreeCellRenderer(@NotNull UsageView view) {
UsageViewTreeCellRenderer(@NotNull UsageViewImpl view) {
myView = view;
myPresentation = view.getPresentation();
}
@@ -150,7 +151,16 @@ class UsageViewTreeCellRenderer extends ColoredTreeCellRenderer {
}
if (node.isValid()) {
TextChunk[] text = node.getUsage().getPresentation().getText();
TextChunk[] text = node.getUsage().getPresentation().getCachedText();
if (text == null) {
// either:
// 1. the node was never updated yet
// 2. the usage presentation have dropped the cached text by itself
// (i.e. it was stored by a soft reference and was gc-ed).
// In either case, `myView.updateLater()` will eventually re-update the visible nodes.
text = ourLoadingText;
myView.updateLater();
}
for (int i = 0; i < text.length; i++) {
TextChunk textChunk = text[i];
SimpleTextAttributes simples = textChunk.getSimpleAttributesIgnoreBackground();