mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
terminal: invoke ChangeListener in EDT (WEB-37538)
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user