diff options
author | Manuel Carrasco Moñino <manuel.carrasco.m@gmail.com> | 2013-03-15 11:17:43 +0100 |
---|---|---|
committer | Manuel Carrasco Moñino <manuel.carrasco.m@gmail.com> | 2013-03-15 11:17:43 +0100 |
commit | 8c21bad7c10bc6fe38366a4ec60d74283319fee5 (patch) | |
tree | 4dec665400b10bb712c900ef07f0adf98d433ac3 | |
parent | d8154713fc443ca709df5aa6401012a22d869a0e (diff) | |
download | gwtquery-8c21bad7c10bc6fe38366a4ec60d74283319fee5.tar.gz gwtquery-8c21bad7c10bc6fe38366a4ec60d74283319fee5.zip |
Create an interface for deferred. Create a utility abtract Promise to facilitate promise creation. Fix a NPE in callbacks
5 files changed, 138 insertions, 21 deletions
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index dbfc8996..c509df6c 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -719,6 +719,15 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> { public static Promise when(Promise... subordinates) { return Deferred.when(subordinates); } + + /** + * A constructor function that returns a chainable utility object with methods to register + * multiple callbacks into callback queues, invoke callback queues, and relay the success + * or failure state of any synchronous or asynchronous function + */ + public static Promise.Deferred Deferred() { + return new Deferred(); + } private static native void scrollIntoViewImpl(Node n) /*-{ if (n) diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java index bb7b24cc..3efccd90 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Promise.java @@ -19,6 +19,31 @@ import com.google.gwt.query.client.Function; * Definition of jquery Promise interface used in gquery. */ public interface Promise { + + /** + * Definition of jquery Deferred interface used in gquery. + */ + public interface Deferred { + /** + * Call the progressCallbacks on a Deferred object with the given args. + */ + Deferred notify(Object... o); + + /** + * Return a Deferred’s Promise object. + */ + Promise promise(); + + /** + * Reject a Deferred object and call any failCallbacks with the given args. + */ + Deferred reject(Object... o); + + /** + * Resolve a Deferred object and call any doneCallbacks with the given args. + */ + Deferred resolve(Object... o); + } public static final String PENDING = "pending"; public static final String REJECTED = "rejected"; diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java index 24d977c6..69c89573 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Deferred.java @@ -23,24 +23,61 @@ import com.google.gwt.query.client.Promise; import com.google.gwt.query.client.plugins.callbacks.Callbacks; /** - * Implementation of jQuery.Deffered for gwtquery. + * Implementation of jQuery.Deferred for gwtquery. */ -public class Deferred extends GQuery { +public class Deferred extends GQuery implements Promise.Deferred { + + /** + * public class used to create customized promises which can manipulate + * the asociated deferred object. + * <pre> + + Promise doSomething = new PromiseFunction() { + @Override + public void f(Deferred dfd) { + dfd.notify("hi"); + dfd.resolve("done"); + } + }; + + doSomething.progress(new Function() { + public void f() { + Window.alert("" + arguments[0]); + } + }).done(new Function() { + public void f() { + Window.alert("" + arguments[0]); + } + }); + + * </pre> + */ + public static abstract class PromiseFunction extends DeferredPromiseImpl { + public PromiseFunction() { + super(null); + f(dfd); + } + + /** + * This function is called once when the promise is created and the + * new deferred is available. + */ + public abstract void f(Deferred dfd); + } /** * Implementation of the Promise interface which is used internally by Deferred. */ - private class DeferredPromise extends GQuery implements Promise { - private Deferred dfd; - - protected DeferredPromise(GQuery gq) { - super(gq); - if (gq instanceof Deferred) { - dfd = (Deferred) gq; - } else if (gq instanceof DeferredPromise) { - dfd = ((DeferredPromise)gq).dfd;; + private static class DeferredPromiseImpl implements Promise { + protected com.google.gwt.query.client.plugins.Deferred dfd; + + protected DeferredPromiseImpl(Object o) { + if (o instanceof com.google.gwt.query.client.plugins.Deferred) { + dfd = (com.google.gwt.query.client.plugins.Deferred) o; + } else if (o instanceof DeferredPromiseImpl) { + dfd = ((DeferredPromiseImpl)o).dfd;; } else { - dfd = gq.as(Deferred); + dfd = new com.google.gwt.query.client.plugins.Deferred(); } } @@ -85,7 +122,7 @@ public class Deferred extends GQuery { /** * Internal Deferred class used to combine a set of subordinate promises. */ - private static class WhenDeferred extends Deferred { + private static class WhenDeferredImpl extends Deferred { /** * Internal function used to track whether all deferred * subordinates are resolved. @@ -98,7 +135,7 @@ public class Deferred extends GQuery { public Object f(Object... args) { values[idx] = args; if (--remaining == 0) { - WhenDeferred.this.resolve(values); + WhenDeferredImpl.this.resolve(values); } return true; } @@ -106,14 +143,14 @@ public class Deferred extends GQuery { private Function failFnc = new Function() { public Object f(Object... o) { - WhenDeferred.this.reject(o); + WhenDeferredImpl.this.reject(o); return true; } }; private Function progressFnc = new Function() { public Object f(Object... o) { - WhenDeferred.this.notify(o); + WhenDeferredImpl.this.notify(o); return true; } }; @@ -124,7 +161,7 @@ public class Deferred extends GQuery { // An indexed array with the fired values of all subordinated private final Object[] values; - public WhenDeferred(Promise[] sub) { + public WhenDeferredImpl(Promise[] sub) { int l = remaining = sub.length; values = new Object[l]; for (int i = 0; i < l; i++) { @@ -149,7 +186,7 @@ public class Deferred extends GQuery { case 0: return new Deferred().resolve().promise(); default: - return new WhenDeferred(d).promise(); + return new WhenDeferredImpl(d).promise(); } } @@ -186,24 +223,35 @@ public class Deferred extends GQuery { }); } + /** + * Call the progressCallbacks on a Deferred object with the given args. + */ public Deferred notify(Object... o) { - notify(o); notify.fire(o); return this; } + /** + * Return a Deferred’s Promise object. + */ public Promise promise() { if (promise == null) { - promise = new DeferredPromise(this); + promise = new DeferredPromiseImpl(this); } return promise; } + /** + * Reject a Deferred object and call any failCallbacks with the given args. + */ public Deferred reject(Object... o) { reject.fire(o); return this; } + /** + * Resolve a Deferred object and call any doneCallbacks with the given args. + */ public Deferred resolve(Object... o) { resolve.fire(o); return this; diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java index 14d3d59d..24ebe685 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/callbacks/Callbacks.java @@ -141,7 +141,7 @@ public class Callbacks { public Callbacks fire(Object... o) { if (!done) { done = opts.getOnce(); - for (Object c : stack.elements()) { + if (stack != null) for (Object c : stack.elements()) { if (!run(c, o) && opts.getStopOnFalse()) { break; } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java index 2cffb6d0..898b3576 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryDeferredTestGwt.java @@ -19,9 +19,12 @@ package com.google.gwt.query.client; import static com.google.gwt.query.client.GQuery.when; import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.query.client.Promise.Deferred; +import com.google.gwt.query.client.plugins.Deferred.PromiseFunction; import com.google.gwt.query.client.plugins.ajax.Ajax; import com.google.gwt.query.client.plugins.callbacks.Callbacks; import com.google.gwt.query.client.plugins.callbacks.Callbacks.Callback; +import com.google.gwt.user.client.Timer; /** * Test class for testing deferred and callbacks stuff. @@ -180,5 +183,37 @@ public class GQueryDeferredTestGwt extends GWTTestCase { } }); } + + int progress = 0; + public void testPromiseFunction() { + delayTestFinish(3000); + + final Promise doSomething = new PromiseFunction() { + public void f(final Deferred dfd) { + new Timer() { + int count = 0; + public void run() { + dfd.notify(count ++); + if (count > 3) { + cancel(); + dfd.resolve("done"); + } + } + }.scheduleRepeating(50); + } + }; + + doSomething.progress(new Function() { + public void f() { + progress = (Integer)arguments[0]; + } + }).done(new Function() { + public void f() { + assertEquals(3, progress); + assertEquals(Promise.RESOLVED, doSomething.state()); + finishTest(); + } + }); + } } |