Replacing the reflection based contract with usage of Executor and instanceof check
1.1 --- a/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java Wed Jan 08 12:58:45 2014 +0100
1.2 +++ b/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java Wed Jan 08 13:07:24 2014 +0100
1.3 @@ -47,6 +47,7 @@
1.4 import java.net.URL;
1.5 import java.util.ArrayList;
1.6 import java.util.List;
1.7 +import java.util.concurrent.Executor;
1.8 import java.util.logging.Level;
1.9 import java.util.logging.Logger;
1.10 import javafx.application.Platform;
1.11 @@ -59,7 +60,8 @@
1.12 *
1.13 * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.14 */
1.15 -public abstract class AbstractFXPresenter implements Fn.Presenter, Fn.ToJavaScript {
1.16 +public abstract class AbstractFXPresenter
1.17 +implements Fn.Presenter, Fn.ToJavaScript, Executor {
1.18 static final Logger LOG = Logger.getLogger(FXPresenter.class.getName());
1.19 protected static int cnt;
1.20 protected List<String> scripts;
1.21 @@ -225,6 +227,14 @@
1.22 return toReturn;
1.23 }
1.24 }
1.25 +
1.26 + @Override public void execute(Runnable r) {
1.27 + if (Platform.isFxApplicationThread()) {
1.28 + r.run();
1.29 + } else {
1.30 + Platform.runLater(r);
1.31 + }
1.32 + }
1.33
1.34 private static final class JSFn extends Fn {
1.35
2.1 --- a/boot-fx/src/main/java/org/netbeans/html/boot/fx/FXPresenter.java Wed Jan 08 12:58:45 2014 +0100
2.2 +++ b/boot-fx/src/main/java/org/netbeans/html/boot/fx/FXPresenter.java Wed Jan 08 13:07:24 2014 +0100
2.3 @@ -95,12 +95,4 @@
2.4 protected WebView findView(final URL resource) {
2.5 return FXBrwsr.findWebView(resource, this);
2.6 }
2.7 -
2.8 - public void runSafe(Runnable r) {
2.9 - if (Platform.isFxApplicationThread()) {
2.10 - r.run();
2.11 - } else {
2.12 - Platform.runLater(r);
2.13 - }
2.14 - }
2.15 }
3.1 --- a/boot/src/main/java/org/apidesign/html/boot/spi/Fn.java Wed Jan 08 12:58:45 2014 +0100
3.2 +++ b/boot/src/main/java/org/apidesign/html/boot/spi/Fn.java Wed Jan 08 13:07:24 2014 +0100
3.3 @@ -51,6 +51,7 @@
3.4 import java.util.HashSet;
3.5 import java.util.Map;
3.6 import java.util.Set;
3.7 +import java.util.concurrent.Executor;
3.8 import net.java.html.js.JavaScriptBody;
3.9 import org.netbeans.html.boot.impl.FnContext;
3.10
3.11 @@ -204,6 +205,13 @@
3.12 * Should be provided by a library included in the application and registered
3.13 * in <code>META-INF/services</code>, for example with
3.14 * <code>@ServiceProvider(service = Fn.Presenter.class)</code> annotation.
3.15 + * <p>
3.16 + * Since 0.7 a presenter may implement {@link Executor} interface, in case
3.17 + * it supports single threaded execution environment. The executor's
3.18 + * {@link Executor#execute(java.lang.Runnable)} method is then supposed
3.19 + * to invoke the runnable immediately (in case we are on the right thread
3.20 + * already) or return and asynchronously invoke the runnable later on the
3.21 + * right thread (if we are on wrong thread).
3.22 */
3.23 public interface Presenter {
3.24 /** Creates new function with given parameter names and provided body.
4.1 --- a/ko-fx/src/main/java/org/netbeans/html/kofx/FXContext.java Wed Jan 08 12:58:45 2014 +0100
4.2 +++ b/ko-fx/src/main/java/org/netbeans/html/kofx/FXContext.java Wed Jan 08 13:07:24 2014 +0100
4.3 @@ -45,8 +45,8 @@
4.4 import java.io.Closeable;
4.5 import java.io.IOException;
4.6 import java.io.InputStream;
4.7 -import java.lang.reflect.Method;
4.8 import java.util.ServiceLoader;
4.9 +import java.util.concurrent.Executor;
4.10 import java.util.logging.Logger;
4.11 import net.java.html.js.JavaScriptBody;
4.12 import org.apidesign.html.boot.spi.Fn;
4.13 @@ -182,11 +182,10 @@
4.14 }
4.15 }
4.16 Wrap w = new Wrap();
4.17 - try {
4.18 - Method m = browserContext.getClass().getMethod("runSafe", Runnable.class);
4.19 - m.invoke(browserContext, w);
4.20 - } catch (Exception ex) {
4.21 - throw new IllegalStateException(ex);
4.22 + if (browserContext instanceof Executor) {
4.23 + ((Executor)browserContext).execute(w);
4.24 + } else {
4.25 + w.run();
4.26 }
4.27 }
4.28