diff --git a/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java b/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java index 0095fe332899..bcfcaa92761e 100644 --- a/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java +++ b/platform/core-api/src/com/intellij/openapi/util/ActionCallback.java @@ -29,7 +29,7 @@ public class ActionCallback implements Disposable { private final ExecutionCallback myDone; private final ExecutionCallback myRejected; - private String myError; + protected String myError; private final String myName; diff --git a/platform/platform-api/src/com/intellij/openapi/util/AsyncResult.java b/platform/platform-api/src/com/intellij/openapi/util/AsyncResult.java index 1d59ae0ade28..b4263e11d3b3 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/AsyncResult.java +++ b/platform/platform-api/src/com/intellij/openapi/util/AsyncResult.java @@ -18,9 +18,12 @@ package com.intellij.openapi.util; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.Consumer; import com.intellij.util.Function; +import com.intellij.util.PairConsumer; import org.jetbrains.annotations.NotNull; public class AsyncResult extends ActionCallback { + private static final Logger LOG = Logger.getInstance(AsyncResult.class); + protected T myResult; @NotNull @@ -49,6 +52,13 @@ public class AsyncResult extends ActionCallback { return subResult; } + @NotNull + public ActionCallback subCallback(@NotNull Consumer doneHandler) { + ActionCallback subCallback = new ActionCallback(); + doWhenDone(new SubCallbackDoneCallback(subCallback, doneHandler)).notifyWhenRejected(subCallback); + return subCallback; + } + @NotNull public AsyncResult doWhenDone(@NotNull final Handler handler) { doWhenDone(new Runnable() { @@ -63,6 +73,7 @@ public class AsyncResult extends ActionCallback { @NotNull public AsyncResult doWhenDone(@NotNull final Consumer consumer) { doWhenDone(new Runnable() { + @Override public void run() { consumer.consume(myResult); } @@ -82,6 +93,17 @@ public class AsyncResult extends ActionCallback { } @Override + @NotNull + public AsyncResult doWhenRejected(@NotNull final PairConsumer consumer) { + doWhenRejected(new Runnable() { + @Override + public void run() { + consumer.consume(myResult, myError); + } + }); + return this; + } + @NotNull public final AsyncResult notify(@NotNull final ActionCallback child) { super.notify(child); @@ -114,8 +136,6 @@ public class AsyncResult extends ActionCallback { // we don't use inner class, avoid memory leak, we don't want to hold this result while dependent is computing private static class SubResultDoneCallback> implements Handler { - private static final Logger LOG = Logger.getInstance(SubResultDoneCallback.class); - private final AsyncSubResult subResult; private final Function doneHandler; @@ -138,4 +158,27 @@ public class AsyncResult extends ActionCallback { subResult.setDone(v); } } + + private static class SubCallbackDoneCallback implements Handler { + private final ActionCallback subResult; + private final Consumer doneHandler; + + public SubCallbackDoneCallback(ActionCallback subResult, Consumer doneHandler) { + this.subResult = subResult; + this.doneHandler = doneHandler; + } + + @Override + public void run(Result result) { + try { + doneHandler.consume(result); + } + catch (Throwable e) { + subResult.reject(e.getMessage()); + LOG.error(e); + return; + } + subResult.setDone(); + } + } } \ No newline at end of file