/** Transforms this future by mapping its result upon arrival. */ public <R> RFuture<R> transform (final Function<Try<? super T>,Try<R>> func) { final RPromise<R> xf = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { Try<R> xfResult; try { xfResult = func.apply(result); } catch (Throwable t) { xf.fail(t); return; } xf.complete(xfResult); } }); return xf; }
/** Transforms this future by mapping its result upon arrival. */ public <R> RFuture<R> transform (final Function<Try<? super T>,Try<R>> func) { final RPromise<R> xf = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { Try<R> xfResult; try { xfResult = func.apply(result); } catch (Throwable t) { xf.fail(t); return; } xf.complete(xfResult); } }); return xf; }
/** Maps a successful result to a new result using {@code func} when it arrives. Failure on the * original result or the mapped result are both dispatched to the mapped result. This is * useful for chaining asynchronous actions. It's also known as monadic bind. */ public <R> RFuture<R> flatMap (final Function<? super T, RFuture<R>> func) { final RPromise<R> mapped = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) mapped.fail(result.getFailure()); else { RFuture<R> mappedResult; try { mappedResult = func.apply(result.get()); } catch (Throwable t) { mapped.fail(t); return; } mappedResult.onComplete(mapped.completer()); } } }); return mapped; }
/** Maps a successful result to a new result using {@code func} when it arrives. Failure on the * original result or the mapped result are both dispatched to the mapped result. This is * useful for chaining asynchronous actions. It's also known as monadic bind. */ public <R> RFuture<R> flatMap (final Function<? super T, RFuture<R>> func) { final RPromise<R> mapped = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) mapped.fail(result.getFailure()); else { RFuture<R> mappedResult; try { mappedResult = func.apply(result.get()); } catch (Throwable t) { mapped.fail(t); return; } mappedResult.onComplete(mapped.completer()); } } }); return mapped; }
/** Returns a future containing a list of all success results from {@code futures}. Any failure * results are simply omitted from the list. The success results are also in no particular * order. If all of {@code futures} fail, the resulting list will be empty. */ public static <T> RFuture<Collection<T>> collect (Collection<? extends RFuture<T>> futures) { // if we're passed an empty list of futures, succeed immediately with an empty list if (futures.isEmpty()) return RFuture.<Collection<T>>success(Collections.<T>emptyList()); final RPromise<Collection<T>> pseq = RPromise.create(); final int count = futures.size(); SignalView.Listener<Try<T>> collector = new SignalView.Listener<Try<T>>() { public synchronized void onEmit (Try<T> result) { if (result.isSuccess()) _results.add(result.get()); if (--_remain == 0) pseq.succeed(_results); } protected final List<T> _results = new ArrayList<T>(); protected int _remain = count; }; for (RFuture<T> future : futures) future.onComplete(collector); return pseq; }
/** Returns a future containing a list of all success results from {@code futures}. Any failure * results are simply omitted from the list. The success results are also in no particular * order. If all of {@code futures} fail, the resulting list will be empty. */ public static <T> RFuture<Collection<T>> collect (Collection<? extends RFuture<T>> futures) { // if we're passed an empty list of futures, succeed immediately with an empty list if (futures.isEmpty()) return RFuture.<Collection<T>>success(Collections.<T>emptyList()); final RPromise<Collection<T>> pseq = RPromise.create(); final int count = futures.size(); SignalView.Listener<Try<T>> collector = new SignalView.Listener<Try<T>>() { public synchronized void onEmit (Try<T> result) { if (result.isSuccess()) _results.add(result.get()); if (--_remain == 0) pseq.succeed(_results); } protected final List<T> _results = new ArrayList<T>(); protected int _remain = count; }; for (RFuture<T> future : futures) future.onComplete(collector); return pseq; }
final RPromise<List<T>> pseq = RPromise.create(); final int count = futures.size(); class Sequencer {
final RPromise<List<T>> pseq = RPromise.create(); final int count = futures.size(); class Sequencer {
/** * Decodes and returns a library synchronously. */ protected static Library decodeLibrarySync (final Platform plat, LibraryData libData, String baseDir) { RPromise<Library> result = RPromise.create(); decodeLibrary(libData, baseDir, result, new ImageLoader() { @Override public Image load (String path) { return plat.assets().getImageSync(path); } }); // this blows, but I don't want to add RPromise.get() final Library[] out = new Library[1]; result.onSuccess(new Slot<Library>() { public void onEmit (Library library) { out[0] = library; } }); assert out[0] != null; return out[0]; }
protected ImageImpl (Platform plat, boolean async, Scale preScale, int preWidth, int preHeight, String source) { this(plat.graphics(), async ? plat.exec().<Image>deferredPromise() : RPromise.<Image>create(), preScale, preWidth, preHeight, source); }
@Override public RFuture<T> next () { final RPromise<T> result = RPromise.create(); connect(result.succeeder()).once(); return result; }
protected ImageImpl (Platform plat, boolean async, Scale preScale, int preWidth, int preHeight, String source) { this(plat.graphics(), async ? plat.exec().<Image>deferredPromise() : RPromise.<Image>create(), preScale, preWidth, preHeight, source); }
@Override public RFuture<T> next () { final RPromise<T> result = RPromise.create(); connect(result.succeeder()).once(); return result; }
/** * Loads a binary encoded library via PlayN assets. * @param baseDir The base directory, containing library.bin and texture atlases. */ public static RFuture<Library> loadLibrary (final Platform plat, final String baseDir) { final RPromise<Library> result = RPromise.create(); plat.assets().getBytes(baseDir + "/library.bin").onSuccess(new Slot<ByteBuffer>() { public void onEmit (ByteBuffer buf) { try { LibraryData libData = new LibraryData(buf); decodeLibraryAsync(plat, libData, baseDir, result); } catch (Exception err) { result.fail(err); } } }); return result; }
private RFuture<XDomainRequest> doXdr(final String path) { final RPromise<XDomainRequest> result = RPromise.create(); XDomainRequest xdr = XDomainRequest.create(); xdr.setHandler(new Handler() { @Override public void onTimeout(XDomainRequest xdr) { plat.log().error("xdr::onTimeout[" + path + "]()"); result.fail(new Exception("Error getting " + path + " : " + xdr.getStatus())); } @Override public void onProgress(XDomainRequest xdr) { if (LOG_XHR_SUCCESS) plat.log().debug("xdr::onProgress[" + path + "]()"); } @Override public void onLoad(XDomainRequest xdr) { if (LOG_XHR_SUCCESS) plat.log().debug("xdr::onLoad[" + path + "]()"); result.succeed(xdr); } @Override public void onError(XDomainRequest xdr) { plat.log().error("xdr::onError[" + path + "]()"); result.fail(new Exception("Error getting " + path + " : " + xdr.getStatus())); } }); if (LOG_XHR_SUCCESS) plat.log().debug("xdr.open('GET', '" + path + "')..."); xdr.open("GET", path); if (LOG_XHR_SUCCESS) plat.log().debug("xdr.send()..."); xdr.send(); return result; }
private RFuture<XDomainRequest> doXdr(final String path) { final RPromise<XDomainRequest> result = RPromise.create(); XDomainRequest xdr = XDomainRequest.create(); xdr.setHandler(new Handler() { @Override public void onTimeout(XDomainRequest xdr) { plat.log().error("xdr::onTimeout[" + path + "]()"); result.fail(new Exception("Error getting " + path + " : " + xdr.getStatus())); } @Override public void onProgress(XDomainRequest xdr) { if (LOG_XHR_SUCCESS) plat.log().debug("xdr::onProgress[" + path + "]()"); } @Override public void onLoad(XDomainRequest xdr) { if (LOG_XHR_SUCCESS) plat.log().debug("xdr::onLoad[" + path + "]()"); result.succeed(xdr); } @Override public void onError(XDomainRequest xdr) { plat.log().error("xdr::onError[" + path + "]()"); result.fail(new Exception("Error getting " + path + " : " + xdr.getStatus())); } }); if (LOG_XHR_SUCCESS) plat.log().debug("xdr.open('GET', '" + path + "')..."); xdr.open("GET", path); if (LOG_XHR_SUCCESS) plat.log().debug("xdr.send()..."); xdr.send(); return result; }
private RFuture<XMLHttpRequest> doXhr(final String path, XMLHttpRequest.ResponseType rtype) { final RPromise<XMLHttpRequest> result = RPromise.create(); XMLHttpRequest xhr = XMLHttpRequest.create(); // IE needs the XHR to be opened before setting the response type if (LOG_XHR_SUCCESS) plat.log().debug("xhr.open('GET', '" + path + "')..."); xhr.open("GET", path); xhr.setResponseType(rtype); xhr.setOnReadyStateChange(new ReadyStateChangeHandler() { @Override public void onReadyStateChange(XMLHttpRequest xhr) { int readyState = xhr.getReadyState(); if (readyState == XMLHttpRequest.DONE) { int status = xhr.getStatus(); // status code 0 will be returned for non-http requests, e.g. file:// if (status != 0 && (status < 200 || status >= 400)) { plat.log().error("xhr::onReadyStateChange[" + path + "]" + "(readyState = " + readyState + "; status = " + status + ")"); result.fail(new Exception("Error getting " + path + " : " + xhr.getStatusText())); } else { if (LOG_XHR_SUCCESS) plat.log().debug("xhr::onReadyStateChange[" + path + "]" + "(readyState = " + readyState + "; status = " + status + ")"); result.succeed(xhr); } } } }); if (LOG_XHR_SUCCESS) plat.log().debug("xhr.send()..."); xhr.send(); return result; }
private RFuture<XMLHttpRequest> doXhr(final String path, XMLHttpRequest.ResponseType rtype) { final RPromise<XMLHttpRequest> result = RPromise.create(); XMLHttpRequest xhr = XMLHttpRequest.create(); // IE needs the XHR to be opened before setting the response type if (LOG_XHR_SUCCESS) plat.log().debug("xhr.open('GET', '" + path + "')..."); xhr.open("GET", path); xhr.setResponseType(rtype); xhr.setOnReadyStateChange(new ReadyStateChangeHandler() { @Override public void onReadyStateChange(XMLHttpRequest xhr) { int readyState = xhr.getReadyState(); if (readyState == XMLHttpRequest.DONE) { int status = xhr.getStatus(); // status code 0 will be returned for non-http requests, e.g. file:// if (status != 0 && (status < 200 || status >= 400)) { plat.log().error("xhr::onReadyStateChange[" + path + "]" + "(readyState = " + readyState + "; status = " + status + ")"); result.fail(new Exception("Error getting " + path + " : " + xhr.getStatusText())); } else { if (LOG_XHR_SUCCESS) plat.log().debug("xhr::onReadyStateChange[" + path + "]" + "(readyState = " + readyState + "; status = " + status + ")"); result.succeed(xhr); } } } }); if (LOG_XHR_SUCCESS) plat.log().debug("xhr.send()..."); xhr.send(); return result; }
public HtmlImage (Graphics gfx, Scale scale, ImageElement elem, String source) { super(gfx, RPromise.<Image>create(), scale, elem.getWidth(), elem.getHeight(), source); img = elem; // we know that in this case, our state is a promise final RPromise<Image> pstate = ((RPromise<Image>)state); if (isComplete(img)) pstate.succeed(this); else { final Scale fscale = scale; HtmlInput.addEventListener(img, "load", new EventHandler() { @Override public void handleEvent (NativeEvent evt) { succeed(new ImageImpl.Data(fscale, img, img.getWidth(), img.getHeight())); } }, false); HtmlInput.addEventListener(img, "error", new EventHandler() { @Override public void handleEvent(NativeEvent evt) { fail(new RuntimeException("Error loading image " + img.getSrc())); } }, false); } }
public HtmlImage (Graphics gfx, Scale scale, ImageElement elem, String source) { super(gfx, RPromise.<Image>create(), scale, elem.getWidth(), elem.getHeight(), source); img = elem; // we know that in this case, our state is a promise final RPromise<Image> pstate = ((RPromise<Image>)state); if (isComplete(img)) pstate.succeed(this); else { final Scale fscale = scale; HtmlInput.addEventListener(img, "load", new EventHandler() { @Override public void handleEvent (NativeEvent evt) { succeed(new ImageImpl.Data(fscale, img, img.getWidth(), img.getHeight())); } }, false); HtmlInput.addEventListener(img, "error", new EventHandler() { @Override public void handleEvent(NativeEvent evt) { fail(new RuntimeException("Error loading image " + img.getSrc())); } }, false); } }