terminal: invoke ChangeListener in EDT (WEB-37538)

This commit is contained in:
Sergey Simonchik
2019-03-01 00:32:42 +03:00
parent f075692e29
commit f15e07bac6
2 changed files with 70 additions and 15 deletions
@@ -0,0 +1,67 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.terminal;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ObservableConsoleView;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean;
public class TerminalConsoleContentHelper implements Disposable {
private static final int FLUSH_TIMEOUT = 200;
private final TerminalExecutionConsole myConsole;
private final Collection<ObservableConsoleView.ChangeListener> myChangeListeners = new CopyOnWriteArraySet<>();
private final Set<ConsoleViewContentType> myContentTypes = ContainerUtil.newConcurrentSet();
private final Alarm myAlarm;
private final AtomicBoolean myRequested = new AtomicBoolean(false);
private volatile boolean myDisposed = false;
public TerminalConsoleContentHelper(@NotNull TerminalExecutionConsole console) {
myConsole = console;
myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD /* won't be disposed to call addRequest safely */);
Disposer.register(console, this);
}
public void addChangeListener(@NotNull ObservableConsoleView.ChangeListener listener, @NotNull Disposable parent) {
myChangeListeners.add(listener);
Disposer.register(parent, () -> myChangeListeners.remove(listener));
}
public void onContentTypePrinted(@NotNull ConsoleViewContentType contentType) {
myContentTypes.add(contentType);
if (myRequested.compareAndSet(false, true) && !myDisposed) {
myAlarm.addRequest(this::flush, FLUSH_TIMEOUT);
}
}
private void flush() {
if (myDisposed) return;
myRequested.set(false);
List<ConsoleViewContentType> contentTypes = new ArrayList<>(myContentTypes);
myContentTypes.removeAll(contentTypes);
for (ConsoleViewContentType contentType : contentTypes) {
fireContentAdded(contentType);
}
}
private void fireContentAdded(@NotNull ConsoleViewContentType contentType) {
List<ConsoleViewContentType> contentTypes = Collections.singletonList(contentType);
for (ObservableConsoleView.ChangeListener listener : myChangeListeners) {
listener.contentAdded(contentTypes);
}
}
@Override
public void dispose() {
myDisposed = true;
myAlarm.cancelAllRequests();
}
}
@@ -49,10 +49,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -65,9 +61,9 @@ public class TerminalExecutionConsole implements ConsoleView, ObservableConsoleV
private final Project myProject;
private final AppendableTerminalDataStream myDataStream;
private final AtomicBoolean myAttachedToProcess = new AtomicBoolean(false);
private final Collection<ChangeListener> myChangeListeners = new CopyOnWriteArraySet<>();
private volatile boolean myLastCR = false;
private final PendingTasksRunner myOnResizedRunner;
private final TerminalConsoleContentHelper myContentHelper = new TerminalConsoleContentHelper(this);
private final TerminalKeyEncoder myKeyEncoder = new TerminalKeyEncoder();
@@ -102,13 +98,12 @@ public class TerminalExecutionConsole implements ConsoleView, ObservableConsoleV
if (contentType != null) {
myDataStream.append((char)CharUtils.ESC + "[39m"); //restore color
}
fireContentAdded(ObjectUtils.notNull(contentType, ConsoleViewContentType.NORMAL_OUTPUT));
myContentHelper.onContentTypePrinted(ObjectUtils.notNull(contentType, ConsoleViewContentType.NORMAL_OUTPUT));
}
@Override
public void addChangeListener(@NotNull ChangeListener listener, @NotNull Disposable parent) {
myChangeListeners.add(listener);
Disposer.register(parent, () -> myChangeListeners.remove(listener));
myContentHelper.addChangeListener(listener, parent);
}
private static String encodeColor(Color color) {
@@ -156,13 +151,6 @@ public class TerminalExecutionConsole implements ConsoleView, ObservableConsoleV
return textCRLF;
}
private void fireContentAdded(@NotNull ConsoleViewContentType contentType) {
List<ConsoleViewContentType> contentTypes = Collections.singletonList(contentType);
for (ChangeListener listener : myChangeListeners) {
listener.contentAdded(contentTypes);
}
}
/**
* Clears history and screen buffers, positions the cursor at the top left corner.
*/