Skip to content

Commit

Permalink
Undeprecate HighlightProblemListener, adds a MergingUpdateQueue to th…
Browse files Browse the repository at this point in the history
…e markup model scan
  • Loading branch information
0verEngineer committed May 24, 2023
1 parent 07adfa2 commit ce8442a
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 24 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
- Support for new EAP versions

### Changed
- HighlightProblemListener is now deprecated
- MarkupModelListener is now the default listener

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.overengineer.inlineproblems;

import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
Expand All @@ -10,7 +11,10 @@
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.overengineer.inlineproblems.entities.InlineProblem;
import org.overengineer.inlineproblems.entities.enums.Listener;
import org.overengineer.inlineproblems.listeners.HighlightProblemListener;
Expand All @@ -23,7 +27,7 @@
import java.util.concurrent.TimeUnit;


public class DocumentMarkupModelScanner {
public class DocumentMarkupModelScanner implements Disposable {
private final ProblemManager problemManager = ApplicationManager.getApplication().getService(ProblemManager.class);

private final Logger logger = Logger.getInstance(DocumentMarkupModelScanner.class);
Expand All @@ -32,18 +36,25 @@ public class DocumentMarkupModelScanner {

private static DocumentMarkupModelScanner instance;

private final MergingUpdateQueue mergingUpdateQueue;

private ScheduledFuture<?> scheduledFuture;

public static final String NAME = "ManualScanner";

public static DocumentMarkupModelScanner getInstance() {
if (instance == null)
instance = new DocumentMarkupModelScanner();

return instance;
}

private DocumentMarkupModelScanner() {
Disposer.register(problemManager, this);

mergingUpdateQueue = new MergingUpdateQueue(
"DocumentMarkupModelScannerQueue",
10,
true,
null,
this,
null,
true
);

SettingsState settingsState = SettingsState.getInstance();
if (settingsState.getEnabledListener() == Listener.MANUAL_SCANNING) {
delayMilliseconds = settingsState.getManualScannerDelay();
Expand All @@ -52,6 +63,18 @@ private DocumentMarkupModelScanner() {
createAndStartScheduledFuture();
}

public static DocumentMarkupModelScanner getInstance() {
if (instance == null)
instance = new DocumentMarkupModelScanner();

return instance;
}

@Override
public void dispose() {
mergingUpdateQueue.cancelAllUpdates();
}

public void scanForProblemsManually() {
ProjectManager projectManager = ProjectManager.getInstanceIfCreated();

Expand All @@ -78,18 +101,27 @@ public void scanForProblemsManually() {
}
}

/**
* This function is queued in the mergingUpdateQueue because it is called frequently, this can be multiple times per
* millisecond if the HighlightProblemListener is used.
*/
public void scanForProblemsManuallyInTextEditor(TextEditor textEditor) {
if (textEditor.getFile() == null) {
return;
}

List<InlineProblem> problems = getProblemsInEditor(textEditor);
mergingUpdateQueue.queue(new Update("scan") {
@Override
public void run() {
List<InlineProblem> problems = getProblemsInEditor(textEditor);

problemManager.updateFromNewActiveProblemsForProjectAndFile(
problems,
textEditor.getEditor().getProject(),
textEditor.getFile().getPath()
);
problemManager.updateFromNewActiveProblemsForProjectAndFile(
problems,
textEditor.getEditor().getProject(),
textEditor.getFile().getPath()
);
}
});
}

private List<InlineProblem> getProblemsInEditor(TextEditor textEditor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class HighlightProblemListener implements HighlightInfoFilter {
private final DocumentMarkupModelScanner markupModelScanner = DocumentMarkupModelScanner.getInstance();
private final SettingsState settingsState = SettingsState.getInstance();
public static final String NAME = "HighlightProblemListener (Deprecated)";
public static final String NAME = "HighlightProblemListener";
public static final int ADDITIONAL_MANUAL_SCAN_DELAY_MILLIS = 2000;

@Override
Expand All @@ -28,9 +28,6 @@ public boolean accept(@NotNull HighlightInfo highlightInfo, @Nullable PsiFile fi
if (file == null || !file.isValid())
return true;

// The HighlightProblemListener is deprecated because the accept function is called a lot of times per second
// and the invokeLater queues the invocations, so this is often called before handleAccept is finished.
// invokeAndWait also doesn't work because it can cause a deadlock.
if (!file.getProject().isDisposed()) {
ApplicationManager.getApplication().invokeLater(() -> handleAccept(file));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class MarkupModelProblemListener implements MarkupModelListener {

private static final List<Disposable> disposables = new ArrayList<>();

public static final String NAME = "MarkupModelListener";
public static final String NAME = "MarkupModelListener (default)";

private enum EventType {
ADD, REMOVE, CHANGE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ public SettingsComponent() {
.addSeparator()
.addComponent(new JBLabel("General"))
.addLabeledComponent(new JBLabel("Enabled problem listener"), enabledListener)
.addTooltip("- MarkupModelListener: Called after addition of a RangeHighlighter to a file. Faster on large files, slower on small ones")
.addTooltip("- ManualScanner: Scans the DocumentMarkupModel for all highlighters at a fixed delay")
.addTooltip("- HighlightProblemListener (DEPRECATED): Faster on small to medium sized files, slower on large ones.")
.addTooltip(" Called way to often and can cause freezes. If you want similar performance use the ManualScanner instead")
.addTooltip("- MarkupModelListener (default): Called after addition of a RangeHighlighter to a file. Faster on large files, slower on small ones")
.addTooltip("- HighlightProblemListener: Faster on small to medium sized files, slower on large ones. Called very often and can cause slowdowns.")
.addTooltip("- ManualScanner: Scans the DocumentMarkupModel for all highlighters at a fixed delay, uses the same logic ")
.addTooltip(" as HighlightProblemListener but can help with slowdowns on big files.")
.addLabeledComponent(new JBLabel("ManualScanner delay in milliseconds"), manualScannerDelay)
.addTooltip("Delay between manual scans, only used when ManualScanner is enabled")
.addComponent(forceErrorsInSameLine, 0)
Expand Down

0 comments on commit ce8442a

Please sign in to comment.