mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
return Promise from AppUIExecutor
This commit is contained in:
@@ -6,7 +6,9 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.CancellablePromise;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@@ -73,5 +75,17 @@ public interface AppUIExecutor extends Executor {
|
||||
@NotNull
|
||||
@Contract(pure=true)
|
||||
AppUIExecutor expireWith(@NotNull Disposable parentDisposable);
|
||||
|
||||
/**
|
||||
* Schedule the given task's execution and return a Promise that allows to get the result when the task is complete,
|
||||
* or cancel the task if it's no longer needed.
|
||||
*/
|
||||
<T> CancellablePromise<T> submit(Callable<T> task);
|
||||
|
||||
/**
|
||||
* Schedule the given task's execution and return a Promise that allows to check if the task is complete,
|
||||
* or cancel the task if it's no longer needed.
|
||||
*/
|
||||
CancellablePromise<?> submit(Runnable task);
|
||||
|
||||
}
|
||||
|
||||
+25
-17
@@ -12,12 +12,14 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.AsyncPromise;
|
||||
import org.jetbrains.concurrency.CancellablePromise;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -163,31 +165,37 @@ class AppUIExecutorImpl implements AppUIExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull Runnable runnable) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
public CancellablePromise<?> submit(Runnable task) {
|
||||
return submit(() -> { task.run(); return null; });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull Runnable command) {
|
||||
submit(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> CancellablePromise<T> submit(Callable<T> task) {
|
||||
AsyncPromise<T> promise = new AsyncPromise<>();
|
||||
|
||||
if (!myDisposables.isEmpty()) {
|
||||
List<Disposable> children = new ArrayList<>();
|
||||
for (Disposable parent : myDisposables) {
|
||||
Disposable child = new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
future.cancel(false);
|
||||
}
|
||||
};
|
||||
Disposable child = promise::cancel;
|
||||
children.add(child);
|
||||
Disposer.register(parent, child);
|
||||
}
|
||||
future.whenComplete((v, t) -> children.forEach(Disposer::dispose));
|
||||
promise.onProcessed(__ -> children.forEach(Disposer::dispose));
|
||||
}
|
||||
|
||||
checkConstraints(runnable, future, new ArrayList<>());
|
||||
checkConstraints(task, promise, new ArrayList<>());
|
||||
return promise;
|
||||
}
|
||||
|
||||
private void checkConstraints(@NotNull Runnable runnable, CompletableFuture<Void> future, List<ConstrainedExecutor> log) {
|
||||
private <T> void checkConstraints(@NotNull Callable<T> task, AsyncPromise<T> future, List<ConstrainedExecutor> log) {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (!app.isDispatchThread()) {
|
||||
app.invokeLater(() -> checkConstraints(runnable, future, log), myModality);
|
||||
app.invokeLater(() -> checkConstraints(task, future, log), myModality);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -199,17 +207,17 @@ class AppUIExecutorImpl implements AppUIExecutor {
|
||||
if (log.size() > 1000) {
|
||||
LOG.error("Too many reschedule requests, probably constraints can't be satisfied all together: " + log.subList(100, 120));
|
||||
}
|
||||
constraint.rescheduleInCorrectContext(() -> checkConstraints(runnable, future, log));
|
||||
constraint.rescheduleInCorrectContext(() -> checkConstraints(task, future, log));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
runnable.run();
|
||||
future.complete(null);
|
||||
T result = task.call();
|
||||
future.setResult(result);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
future.completeExceptionally(e);
|
||||
future.setError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user