From e5f6093e082f46ccb98bf8df8c236bfbfdcaa14a Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 26 Apr 2018 10:16:22 +0200 Subject: [PATCH] return Promise from AppUIExecutor --- .../openapi/application/AppUIExecutor.java | 14 +++++++ .../application/impl/AppUIExecutorImpl.java | 42 +++++++++++-------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/application/AppUIExecutor.java b/platform/core-api/src/com/intellij/openapi/application/AppUIExecutor.java index 63a380be5a91..b7ef24b8791c 100644 --- a/platform/core-api/src/com/intellij/openapi/application/AppUIExecutor.java +++ b/platform/core-api/src/com/intellij/openapi/application/AppUIExecutor.java @@ -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. + */ + CancellablePromise submit(Callable 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); } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/AppUIExecutorImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/AppUIExecutorImpl.java index 248247e724d8..8cdc0f65c7ac 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/AppUIExecutorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/AppUIExecutorImpl.java @@ -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 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 CancellablePromise submit(Callable task) { + AsyncPromise promise = new AsyncPromise<>(); if (!myDisposables.isEmpty()) { List 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 future, List log) { + private void checkConstraints(@NotNull Callable task, AsyncPromise future, List 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); } }